Pues nada chicos, nunca me habia tocado trabajar con codificacion de archivos en php asi que espero de su ayuda en la solucion de este problema.
1. Tengo unos archivos .rcx y el codigo se encarga de leer el archivo y convertirlo a codigo ascii para su posterior uso en php:
Cdigo PHP:
function ReturnRecGameXml($fileName)
{
define( "GAME_SETTINGS_BLOCKSIZE", 0x400 );
define( "GAMESETTINGSOFFSET", 0x59A );
define( "TITAN_ADDITIONAL_SETTINGS_OFFSET", 0x28 );
define( "GAME_SETTINGS_STARTTAG", ASCIItoUTF16( '<GameSettings>' ) );
define( "GAME_SETTINGS_ENDTAG", ASCIItoUTF16( '</GameSettings>' ) );
global $_REAL_CIV;
$xml="";
$xPack=0; //0-> AoM, 1->Titans
$fp = fopen($fileName, "r");
//---- Make sure the file opened
if($fp == null) {
return false;
}
else{
//---- Check the header bytes are correct = 'l33t'
$header = fread($fp, 4); //its a 4 byte header
if($header != "l33t"){
return false;
}else{
//---- See how many bytes the uncompressed data will expand to
$sizeBytes = fread($fp, 4);
$size = (int) ord($sizeBytes[0]) //get original file size
+ (ord($sizeBytes[1]) << 8)
+ (ord($sizeBytes[2]) << 16)
+ (ord($sizeBytes[3]) << 24);
$compressedData = fread($fp, filesize($fileName)-8);
$uncompressed = gzuncompress($compressedData, $size);
//---- Check to make sure the uncompressed data is valid
//---- See if we can extract the XML data from the random mess
$uc_nullfree = substr($uncompressed, GAMESETTINGSOFFSET);
//---- Check of this as an AoM game, or an AoT game
if(strpos($uc_nullfree, GAME_SETTINGS_STARTTAG) == 2)
$xPack = 0;
else
{
$uc_nullfree = substr($uc_nullfree, TITAN_ADDITIONAL_SETTINGS_OFFSET);
if(strpos($uc_nullfree, GAME_SETTINGS_STARTTAG) == 2)
$xPack = 1;
else
return false;
}
$final = "";
$pos = 0;
$end = strpos($uc_nullfree, GAME_SETTINGS_ENDTAG);
$skipSize = 4;
while($pos < $size)
{
$final .= substr($uc_nullfree, $pos, GAME_SETTINGS_BLOCKSIZE);
$pos += GAME_SETTINGS_BLOCKSIZE + $skipSize;
if($pos > $end) //there was a skip after the xml where no skip should be... this should work
$skipSize=0;
}
//---- Extract the XML from the data
$end = strpos($final, GAME_SETTINGS_ENDTAG);
$xml = substr($final, 2, $end-2);
/*$xml = strstr($final, GAME_SETTINGS_ENDTAG);*/
//---- Convert the UTF-16 UNICODE into 8 bit ASCII
/*Codigo que agregue para sanear el codigo*/
if(strpos($xml, '//')){
$slash = strpos($xml, '//') - 45;
$sane = substr( $xml, 0, $slash );
$xml = UTF16toASCII($sane);
}else{
$xml = UTF16toASCII($xml);
}
//---- BINARY FIXES
//-- This finds the Actual Team # for the players, no 255 in here!!
$start = strpos($final, "Team #", 0);
$first_start = $start;
while($start !== false)
{
$teamstr = substr($final, $start, 100);
for($m=0; $m<ord($teamstr[7]); $m++)
{
$xml .= "\t<REALTEAM TeamId=\"".($teamstr[6]-1)."\" PlayerId=\"".(ord($teamstr[7 + (4*($m+1))])-1)."\" ></REALTEAM>\n";
}
$start = strpos($final, "Team #", $start+6);
};
//-- We can't actually extract the player names yet, until we have XML decoded
//-- so we have to store the REALCIVILIZATION memory block in a global for now
//-- Grab too much, we can refine it later.. (cubensis)
if( $first_start !== false ) $_REAL_CIV = substr( $final, $first_start, 4000 );
//---- Format the XML, with the inserted tags
$ret_xml = "<GameSettings>\n";
$ret_xml .= "\t<XPACK>".$xPack."</XPACK>\n";
$ret_xml .= substr($xml, strlen("<GameSettings>"));
$ret_xml .= "</GameSettings>";
return $ret_xml;
}
}
}
function UTF16toASCII( $unicode )
{
$data = "";
//---- Implemented a slightly cleaner way of doing this, which doesn't compress 0 value pairs
$i = -2;
$len = strlen( $unicode );
while( $i < $len ) $data .= $unicode[$i+=2];
return $data;
}
//- (cubensis)
function ASCIItoUTF16( $ascii )
{
$data = "";
$len = strlen( $ascii );
for( $i = 0; $i < $len; $i++ )
{
$data .= $ascii[$i];
$data .= chr(0);
}
return $data;
}
2. En la mayoria de los archivos todo funciona bien pero algunos me presentan errores como estos:
Cdigo:
1 2 midgard 3 652172367 1433792346 0 1 0 0 1 0 25367 0 7 BlackAdder_ 0.000000 4 0 0 0 0 [Lad_]simtom 0.000000 0 0 0 1 8 [DoD]Titou 0.000000 0 0 0 2 10 IamAurelien 0.000000 0 0 0 1 8 [DoD]KiLLerB0y_ 0.000000 0 0 0 2 8 IKill_UDie 0.000000 0 0 0 1 10 S_to_the_pOefT 0.000000 0 0 0 2 3 anetypitfrrno a cit odmi(od { / et rStttset",.1; / e ie n lyrie=20; i(Mpie= ) { lyrie 50; mcono"ag a"; } itsz=.*qtcubroGiPaespaeTls; rEhIf(Mpsz=+ie" +ie""; rStaSz(ie ie; / e pdfutwtr meSaee7?h5555ddd!!!!!!....
Lo normal es algo como esto:
Cdigo:
1 2 midgard 3 652172367 1433792346 0 1 0 0 1 0 25367 0 7 BlackAdder_ 0.000000 4 0 0 0 0 [Lad_]simtom 0.000000 0 0 0 1 8 [DoD]Titou 0.000000 0 0 0 2 10 IamAurelien 0.000000 0 0 0 1 8 [DoD]KiLLerB0y_ 0.000000 0 0 0 2 8 IKill_UDie 0.000000 0 0 0 1 10 S_to_the_pOefT 0.000000 0 0 0 2 3
3.- Entonces lo que hice fue sanear el codigo, con un pequeo codigo que agregue a la funcion principal.
4.- Hasta ahi bien, pero el problema surge cuando quiero convertir el UTF-16 a codigo ASCII. Analizando el codigo me di cuenta que despues de hacer la conversion a ASCII el codigo presenta este tipo de errores (cosa que con la mayoria de los archivos funcionan bien):
Cdigo:
<transformcolor1>0
<transformcolor2>0</transformcolor2>
<team>1</team>
<civilization>8</civilization>
<aipersonality></aipersonality>
</transformcolor1>
Cuando debera ser as:
Cdigo:
<transformcolor1>0</transformcolor1>
<transformcolor2>0</transformcolor2>
<team>1</team>
<civilization>8</civilization>
<aipersonality></aipersonality>
5.- Aclaro que me interesa esto debido a que despus de obtener el cdigo necesito parsearlo para convertirlo en array , pero con este error no me funciona el parseo.
Y ahi es la parte donde no se como resolverlo, o no se si el error surge al inicio del codigo, la verdad no lo se. AYUDA!!!