15) { echo "Character name must be between 2 and 15 characters long."; // You can handle the error case accordingly (e.g., return an error response) // Additional validation checks can be added here as needed } else { // Validate the character name format $pattern = '/^[A-Za-z0-9_-]+$/'; // Regular expression pattern for allowed characters if (!preg_match($pattern, $value)) { echo "\nCharacter name contains invalid characters. Only alphabets, numbers, underscore, and dash are allowed."; // Handle the error case accordingly } else { // The character name is valid, proceed with further processing $char->setChar($cmd, $value); echo "\nCharacter Name and filename Changed"; } } echo "\nHandling CharacterName command - Name: $value, File Path: $filePath"; break; case "CharacterClass": // Handle CharacterClass command $char->setChar($cmd, $value); echo "Handling CharacterClass command - Class: $value, File Path: $filePath"; break; case "CharacterLevel": // Handle CharacterLevel command $char->setChar($cmd, $value); echo "Handling CharacterLevel command - Level: $value, File Path: $filePath"; break; // handle difficulty wierdly case "Normal": $char->setChar("CharacterProgression", $value); echo "Handling Difficulty command - Difficulty: $value, File Path: $filePath"; break; case "Finished Normal": $char->setChar("CharacterProgression", $value); echo "Handling Difficulty command - Difficulty: $value, File Path: $filePath"; break; case "Finished Nightmare": $char->setChar("CharacterProgression", $value); echo "Handling Difficulty command - Difficulty: $value, File Path: $filePath"; break; case "Finished Hell": $char->setChar("CharacterProgression", $value); echo "Handling Difficulty command - Difficulty: $value, File Path: $filePath"; break; // skills case "skills": //var_dump($char->cData); $char->setSkill($name, $value); echo "Handling skills command - Skill: $name, Value: $value, File Path: $filePath"; break; case "Died": $char->setChar("CharacterStatus", "Died", $value); // Set the "CharacterStatusDied" value to the provided value echo "Handling Died command - Value: $value, File Path: $filePath"; // Display a message indicating the handling of the Died command break; case "Expansion": $char->setChar("CharacterStatus", "Expansion", $value); // Set the "CharacterStatusExpansion" value to the provided value echo "Handling Expansion command - Value: $value, File Path: $filePath"; // Display a message indicating the handling of the Expansion command break; case "Hardcore": $char->setChar("CharacterStatus", "Hardcore", $value); // Set the "CharacterStatusHardcore" value to the provided value echo "Handling Hardcore command - Value: $value, File Path: $filePath"; // Display a message indicating the handling of the Hardcore command break; // Handle the WP check/uncheck case "wp": $diff = $g['diff']; if ($diff == "Norm") { $offset = 643; } if ($diff == "NM") { $offset = 667; } if ($diff == "Hell") { $offset = 691; } /* array (size=5) 'cmd' => string 'wp' (length=2) 'name' => string '1' (length=1) 'value' => string '1' (length=1) 'filePath' => string 'D:\\Diablo II\\MODS\\ironman-dev\\save\\Sorc.d2s' (length=48) 'diff' => string 'Norm' (length=4) */ $fileContents = file_get_contents($filePath); // Read the contents of the file $ByteReader = new D2ByteReader($fileContents); // Create a new instance of D2ByteReader with the file data $fileData = $ByteReader->getData(); // Get the data from the ByteReader instance $wpBytes = $ByteReader->read($offset, 5, 1); $wpBytesToBits = $ByteReader->toBits($wpBytes); $BitReader = new D2BitReader($wpBytesToBits); $BitReader->setBit($g['name'], $g['value']); $newBits = $BitReader->getBits(); $newBitsToBytes = $ByteReader->bitsToHexString($newBits); $ByteReader->writeBytes($offset, $newBitsToBytes); $newFileData = $ByteReader->getData(); $fileSaved = file_put_contents($filePath, $newFileData); $checksum = (shell_exec("bin\d2scs.exe \"$filePath\"")); if ($fileSaved) { echo "Success"; } else { echo "Fail"; } break; /* * array (size=5) 'cmd' => string 'q' (length=1) 'name' => string 'Sisters_Burial_Grounds' (length=29) 'value' => string '1' (length=1) 'filePath' => string 'D:\\Diablo II\\MODS\\ironman-dev\\save\\Sorc.d2s' (length=48) 'diff' => string 'Norm' (length=4) At each quest offset, read a short, 2 bytes. 347 => 'Den_Of_Evil', 349 => 'Sisters_Burial_Grounds', 351 => 'Tools_Of_The_Trade', 353 => 'The_Search_For_Cain', 355 => 'The_Forgotten_Tower', 357 => 'Sisters_To_The_Slaughter', Each short is 16 bytes. * * 0xFEFF = 11111110 11111111 * Short #0 Den of Evil Bit 4 is set when you enter the Den. */ case "q": $diff = $g['diff']; if ($diff == "Norm") { $qArray = array_flip($csData->qNorm); $questOffset = $qArray[$g['name']]; } if ($diff == "NM") { $qArray = array_flip($csData->qNM); $questOffset = $qArray[$g['name']]; } if ($diff == "Hell") { $qArray = array_flip($csData->qHell); $questOffset = $qArray[$g['name']]; } // Open the file in binary mode for both reading and writing $fp = fopen($filePath, "rb+"); if ($g['value']) { // Set the file pointer position to the quest offset fseek($fp, $questOffset); // Write the byte value 0xFE at the current position fwrite($fp, pack('C', 0xFE)); // Move the file pointer to the next position fseek($fp, $questOffset + 1); // Write the byte value 0xFF at the current position fwrite($fp, pack('C', 0xFF)); echo "Quest Just Finished, Collect Reward!"; } else { // Set the file pointer position to the quest offset fseek($fp, $questOffset); // Write the byte value 0xFE at the current position fwrite($fp, pack('C', 0x00)); // Move the file pointer to the next position fseek($fp, $questOffset + 1); // Write the byte value 0xFF at the current position fwrite($fp, pack('C', 0x00)); echo "Quest Not Started Yet!"; } $checksum = (shell_exec("bin\d2scs.exe \"$filePath\"")); fclose($fp); break; // stats commands case "stats": echo "Handling $name command. New value: $value"; $char->setStat($name, $value); break; // setallskills case "setallskills": echo "Handling $name command. New value: $value"; $char->setAllSkills($value); break; // q_all case "q_all": echo "Handling $name command. New value: $value"; $fp = fopen($filePath, "rb+"); $offsets = array_merge(array_keys($csData->qNorm), array_keys($csData->qNM), array_keys($csData->qHell)); $packValue1 = ($value == 1) ? 0xFE : 0x00; $packValue2 = ($value == 1) ? 0xFF : 0x00; foreach ($offsets as $k => $v) { fseek($fp, $v); fwrite($fp, pack('C', $packValue1)); fseek($fp, $v + 1); fwrite($fp, pack('C', $packValue2)); } $checksum = (shell_exec("bin\d2scs.exe \"$filePath\"")); break; // wp_all case "wp_all": echo "Handling $name command. New value: $value"; $fp = fopen($filePath, "rb+"); // Determine the pack value based on the $value variable $packValue = ($value == 1) ? 0xFF : 0x00; // Define the WP offsets $wp_offsets = [ 643, 644, 645, 646, 647, // Norm 667, 668, 669, 670, 671, // NM 691, 692, 693, 694, 695 // Hell ]; // Iterate over the WP offsets foreach ($wp_offsets as $offset) { fseek($fp, $offset); fwrite($fp, pack('C', $packValue)); } $checksum = (shell_exec("bin\d2scs.exe \"$filePath\"")); break; // default command default: // Handle unknown command echo "Unknown command: $cmd"; break; }