c2ephp
|
00001 <?php 00002 00003 require_once(dirname(__FILE__).'/../../support/StringReader.php'); 00004 require_once(dirname(__FILE__).'/../../support/Archiver.php'); 00005 require_once(dirname(__FILE__).'/CreaturesArchiveBlock.php'); 00006 require_once(dirname(__FILE__).'/../CreatureHistory/CreatureHistory.php'); 00007 00011 00013 define('GLST_FORMAT_UNKNOWN',0); 00015 define('GLST_FORMAT_C3',1); 00017 define('GLST_FORMAT_DS',2); 00019 00021 class GLSTBlock extends CreaturesArchiveBlock { 00022 00024 00025 private $history; 00026 private $format = GLST_FORMAT_UNKNOWN; 00027 00029 00031 00041 public function GLSTBlock($object,$name,$content,$flags) { 00042 parent::CreaturesArchiveBlock($object,$name,$content,$flags,PRAY_BLOCK_GLST); 00043 if($object instanceof PRAYFile) { 00044 //Do nothing! Decoding is automated later now :) 00045 } else if($object instanceof CreatureHistory) { 00046 $this->history = $object; 00047 } else { 00048 throw new Exception('Couldn\'t create a GLST block. :('); 00049 } 00050 } 00051 00053 private function GuessFormat() { 00054 //if I don't know 00055 if($this->format == GLST_FORMAT_UNKNOWN) { 00056 //ask $prayfile if it exists. (look for DSEX, otherwise C3) 00057 if($this->prayfile != null) { 00058 //prayfile should know 00059 if(sizeof($this->prayfile->GetBlocks(PRAY_BLOCK_DSEX)) > 0) { 00060 $format = GLST_FORMAT_DS; 00061 } else { 00062 $format = GLST_FORMAT_C3; 00063 } 00064 } else { 00065 //history will know. (Though it could be wrong) 00066 $format = $this->history->GuessFormat(); 00067 } 00068 //cache so I don't need to ask again :) 00069 $this->format = $format; 00070 } 00071 return $this->format; 00072 } 00073 00074 00076 public function GetHistory() { 00077 $this->EnsureDecompiled(); 00078 return $this->history; 00079 } 00080 00083 00092 public function GetPHOTBlockName(CreatureHistoryEvent $event) { 00093 $photoname = $event->GetPhotoGraph(); 00094 if(empty($photoname)) { 00095 return null; 00096 } 00097 if($this->format == GLST_FORMAT_DS) { 00098 return $photoname.'.DSEX.photo'; 00099 } else { 00100 return $photoname.'.photo'; 00101 } 00102 } 00103 00106 00111 public function GetPhotoBlock(CreatureHistoryEvent $event) { 00112 if($this->GetPrayFile() instanceof PRAYFile) { 00113 return $block = $this->GetPrayFile()->GetBlockByName($this->GetPHOTBlockName()); 00114 } else { 00115 throw new Exception("This GLSTBlock is not connected to a PRAYFile."); 00116 } 00117 } 00118 00120 00123 protected function DecompileBlockData() { 00124 $reader = new StringReader($this->GetData()); 00125 $firstchar = $reader->Read(1); 00126 if($firstchar == chr(0x27)) { //apostrophe thing 00127 //ds 00128 $this->format = GLST_FORMAT_DS; 00129 } else if($firstchar == chr(0x0C)) { //control character 00130 //c3 00131 $this->format = GLST_FORMAT_C3; 00132 } else { 00133 throw new Exception("Couldn't guess the format."); 00134 } 00135 //the first four bytes including $firstchar are probably one integer used to identify the game used. 00136 //We read the first one above and now we're skipping the next three. 00137 $reader->Skip(3); // 3 nulls. 00138 if($reader->ReadInt(4)!=1) { //Always 1, don't know why. 00139 throw new Exception('Either the GLST Block is corrupt or I don\'t understand what the 2nd set of 4 bytes mean.'); 00140 return false; 00141 } 00142 $moniker = $reader->Read($reader->ReadInt(4)); 00143 $reader->Skip($reader->ReadInt(4)); //second moniker is always identical and never necessary. 00144 $name = $reader->Read($reader->ReadInt(4)); 00145 $gender = $reader->ReadInt(4); 00146 $genus = $reader->ReadInt(4); //0 for norn, 1 for grendel, 2 for ettin 00147 $species = $reader->ReadInt(4); 00148 $eventslength = $reader->ReadInt(4); 00149 00150 $this->history = new CreatureHistory($moniker,$name,$gender,$genus,$species); 00151 if(!isset($eventslength)) { 00152 return false; 00153 } 00154 for($i=0;$i<$eventslength;$i++) { 00155 $this->DecodeEvent($reader); 00156 } 00157 00158 //reading the footer 00159 $mutations = $reader->ReadInt(4); 00160 $crossovers = $reader->ReadInt(4); 00161 00162 $this->history->SetMutationsAndCrossovers($mutations,$crossovers); 00163 00164 if($this->format == GLST_FORMAT_DS) { 00165 $unknown1 = $reader->ReadInt(4); 00166 $warpveteran = (($reader->ReadInt(4)==1)?1:0); 00167 $unknown2 = $reader->Read($reader->ReadInt(4)); 00168 $this->history->SetDSUnknowns($unknown1,$unknown2); 00169 $this->history->SetWarpVeteran($warpveteran); 00170 } 00171 } 00172 00173 00175 private function DecodeEvent($reader) { 00176 $eventNumber = $reader->ReadInt(4); 00177 //echo 'Event '.$eventNumber."\n"; 00178 if($eventNumber < 18) { 00179 $eventnumber = $eventNumber; 00180 $worldtime = $reader->ReadInt(4); 00181 $creatureage = $reader->ReadInt(4); 00182 $timestamp = $reader->ReadInt(4); 00183 $lifestage = $reader->ReadInt(4); 00184 $moniker = $reader->Read($reader->ReadInt(4)); 00185 $moniker2 = $reader->Read($reader->ReadInt(4)); 00186 $usertext = $reader->Read($reader->ReadInt(4)); 00187 $photograph = $reader->Read($reader->ReadInt(4)); 00188 $worldname = $reader->Read($reader->ReadInt(4)); 00189 $worldUID = $reader->Read($reader->ReadInt(4)); 00190 $event = new CreatureHistoryEvent($eventnumber,$worldtime,$creatureage, 00191 $timestamp,$lifestage,$moniker,$moniker2,$usertext,$photograph, 00192 $worldname,$worldUID); 00193 if($this->format == GLST_FORMAT_DS) { 00194 $DSUser = $reader->Read($reader->ReadInt(4)); 00195 $unknown1 = $reader->ReadInt(4); 00196 $unknown2 = $reader->ReadInt(4); 00197 $event->AddDSInfo($DSUser,$unknown1,$unknown2); 00198 } 00199 $this->history->AddEvent($event); 00200 return true; 00201 } 00202 return false; 00203 } 00204 00205 00207 00211 protected function CompileBlockData($format=GLST_FORMAT_UNKNOWN) { 00212 //if you don't know 00213 if($format == GLST_FORMAT_UNKNOWN) { 00214 $format = $this->GuessFormat(); 00215 } 00216 $compiled = Archive($this->history->Compile($format)); 00217 return $compiled; 00218 } 00219 00221 } 00222 ?>