mirror of
https://gitlab.com/hashborgir/d2tools.git
synced 2025-10-13 16:34:23 -05:00
Refactored into classes, now just need to display data, and later create editing form
This commit is contained in:
@@ -51,20 +51,25 @@ if (!empty($_POST)) {
|
||||
$modname = str_replace(' ', '', $_POST['modname']);
|
||||
$_SESSION['modname'] = $modname;
|
||||
$time = time();
|
||||
$savePath = '';
|
||||
// write the D2Modder.db file and replace \ with \\
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
$path = rtrim($_POST['path'], "\\");
|
||||
$path = str_replace("\\", "\\\\", $path);
|
||||
|
||||
$savePath .= $path . '\\\\save\\\\';
|
||||
$tbl = $path.'\\\\data\\\\local\\\\lng\\\\eng\\\\';
|
||||
|
||||
$path .= '\\\\data\\\\global\\\\excel\\\\';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PDO_Connect("sqlite:../D2Modder.db");
|
||||
$sql = "CREATE TABLE IF NOT EXISTS D2Modder (
|
||||
modname VARCHAR(255),
|
||||
path VARCHAR(255),
|
||||
path VARCHAR(255),
|
||||
tbl VARCHAR(255),
|
||||
lastused INT,
|
||||
theme INT
|
||||
@@ -80,6 +85,7 @@ ERROR: INVALID PATH</h1></center>';
|
||||
// set this mod to active mod in session
|
||||
$_SESSION['path'] = $path;
|
||||
$_SESSION['tbl'] = $tbl;
|
||||
$_SESSION['savePath'] = $savePath;
|
||||
// Don't yell at me, security is the least of my considerations atm
|
||||
// check modname in db
|
||||
$sql = "SELECT * FROM D2Modder WHERE modname=?";
|
||||
|
108
src/D2Files.php
108
src/D2Files.php
@@ -1,64 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 2021 Hash Borgir
|
||||
Copyright (C) 2021 Hash Borgir
|
||||
|
||||
This file is part of D2Modder
|
||||
This file is part of D2Modder
|
||||
|
||||
Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* This software must not be used for commercial purposes
|
||||
* without my consent. Any sales or commercial use are prohibited
|
||||
* without my express knowledge and consent.
|
||||
* This software must not be used for commercial purposes
|
||||
* without my consent. Any sales or commercial use are prohibited
|
||||
* without my express knowledge and consent.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY!
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY!
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
class D2Files {
|
||||
|
||||
public $files = [];
|
||||
public $files = [];
|
||||
public $charFiles;
|
||||
|
||||
public function __construct() {
|
||||
$filesToIgnore = [
|
||||
"aiparms.txt",
|
||||
"shrines.txt",
|
||||
"cubemain.txt", // cubemain is processed manually in sqlite cli tool
|
||||
"misc.txt", // grew too large, process manually in processmanually function
|
||||
"treasureclass.txt",
|
||||
"treasureclassex.txt"
|
||||
];
|
||||
$glob = glob($_SESSION['path'] . '*.txt');
|
||||
foreach ($glob as $g) {
|
||||
$files[] = basename($g);
|
||||
}
|
||||
$this->files = array_udiff($files, $filesToIgnore, 'strcasecmp');
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
public function getSaveFiles() {
|
||||
$glob = glob($_SESSION['savePath'] . '*.d2s');
|
||||
|
||||
|
||||
foreach ($glob as $g) {
|
||||
$this->charFiles[] = basename($g);
|
||||
}
|
||||
|
||||
return $this->charFiles;
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
$filesToIgnore = [
|
||||
"aiparms.txt",
|
||||
"shrines.txt",
|
||||
"cubemain.txt", // cubemain is processed manually in sqlite cli tool
|
||||
"misc.txt", // grew too large, process manually in processmanually function
|
||||
"treasureclass.txt",
|
||||
"treasureclassex.txt"
|
||||
];
|
||||
$glob = glob($_SESSION['path'].'*.txt');
|
||||
foreach ($glob as $g){
|
||||
$files[] = basename($g);
|
||||
}
|
||||
$this->files = array_udiff($files, $filesToIgnore, 'strcasecmp');
|
||||
return $this->files;
|
||||
}
|
||||
}
|
||||
|
@@ -41,20 +41,36 @@
|
||||
|
||||
*/
|
||||
function ddump($var) {
|
||||
//echo "<pre>";
|
||||
//var_dump($var);
|
||||
//echo "</pre>";
|
||||
echo "<pre>";
|
||||
var_dump($var);
|
||||
echo "</pre>";
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($var, JSON_INVALID_UTF8_IGNORE | JSON_PRETTY_PRINT);
|
||||
// header('Content-Type: application/json');
|
||||
// echo json_encode($var, JSON_INVALID_UTF8_IGNORE | JSON_PRETTY_PRINT);
|
||||
die();
|
||||
}
|
||||
|
||||
function dump($var) {
|
||||
//echo "<pre>";
|
||||
//echo "$var";
|
||||
//echo "</pre>";
|
||||
echo "<pre>";
|
||||
echo "$var";
|
||||
echo "</pre>";
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($var, JSON_INVALID_UTF8_IGNORE | JSON_PRETTY_PRINT);
|
||||
//header('Content-Type: application/json');
|
||||
//echo json_encode($var, JSON_INVALID_UTF8_IGNORE | JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
|
||||
function strtobits(string $str): string {
|
||||
$ret = "";
|
||||
for ($i = 0; $i < strlen($str); ++$i) {
|
||||
$ord = ord($str[$i]);
|
||||
for ($bitnum = 7; $bitnum >= 0; --$bitnum) {
|
||||
if ($ord & (1 << $bitnum)) {
|
||||
$ret .= "1";
|
||||
} else {
|
||||
$ret .= "0";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
226
src/D2SaveFile.php
Executable file → Normal file
226
src/D2SaveFile.php
Executable file → Normal file
@@ -1,91 +1,135 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 2021 Hash Borgir
|
||||
|
||||
This file is part of D2Modder
|
||||
|
||||
Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* This software must not be used for commercial purposes
|
||||
* without my consent. Any sales or commercial use are prohibited
|
||||
* without my express knowledge and consent.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY!
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
class D2SaveFile {
|
||||
|
||||
public $path;
|
||||
|
||||
public function save($file, $data) {
|
||||
|
||||
$fp = fopen($this->path.DIRECTORY_SEPARATOR.$file, 'a+');
|
||||
$this->saveBackup($file);
|
||||
fputcsv($fp, $data, "\t");
|
||||
}
|
||||
|
||||
|
||||
public function saveBackup($file){
|
||||
|
||||
// if dir doesn't exist, create it
|
||||
if (!is_dir($this->path.DIRECTORY_SEPARATOR."backup")) mkdir($this->path."backup", 0700);
|
||||
|
||||
$oldfile = $this->path.$file;
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
// set new file location to copy to (backup)
|
||||
$newfile = $this->path."\\backup\\$file";
|
||||
} else {
|
||||
$newfile = $this->path."backup/$file";
|
||||
}
|
||||
if (!copy($oldfile, $newfile)) {
|
||||
echo "Failed to create backup of $file...\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function saveTblEnries($filename) {
|
||||
$post = $_POST;
|
||||
|
||||
if (!is_dir($this->path."tblEntries")) mkdir($this->path."tblEntries", 0700);
|
||||
|
||||
// write for .tbl
|
||||
$str = '"'.$post['index'].'"'."\t".'"'.$post['index'].'"'.PHP_EOL;
|
||||
$file = $this->path."\\tblEntries\\$filename";
|
||||
file_put_contents($file, $str, FILE_APPEND);
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
$this->path = TXT_PATH;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
|
||||
|
||||
require_once 'D2SaveFileStructureData.php';
|
||||
require_once 'D2Files.php';
|
||||
|
||||
|
||||
class D2SaveFile {
|
||||
|
||||
public $charData;
|
||||
|
||||
public function __construct() {
|
||||
|
||||
$sdata = new D2SaveFileStructureData();
|
||||
|
||||
$D2Files = new D2Files();
|
||||
$files = $D2Files->getSaveFiles();
|
||||
|
||||
foreach ($files as $f) {
|
||||
$filePath = $_SESSION['savePath'] . $f;
|
||||
|
||||
$fp = fopen($filePath, "rb+");
|
||||
|
||||
|
||||
foreach ($sdata->qNorm as $k => $v) {
|
||||
fseek($fp, $k);
|
||||
$questsNorm[$k] = fread($fp, 2);
|
||||
}
|
||||
|
||||
foreach ($sdata->qNM as $k => $v) {
|
||||
fseek($fp, $k);
|
||||
$questsNM[$k] = fread($fp, 2);
|
||||
}
|
||||
|
||||
foreach ($sdata->qHell as $k => $v) {
|
||||
fseek($fp, $k);
|
||||
$questsHell[$k] = fread($fp, 2);
|
||||
}
|
||||
|
||||
|
||||
// read offsets here from sdata and put into $data which will be used for charData
|
||||
|
||||
foreach ($sdata->offsets as $k => $v) {
|
||||
fseek($fp, $k);
|
||||
$data[$k] = fread($fp, $v);
|
||||
}
|
||||
|
||||
$charData['Identifier'] = bin2hex($data[0]);
|
||||
|
||||
$charData['VersionID'] = $sdata->version[unpack('l', $data[4])[1]]; // 96 is v1.10+ - check out
|
||||
|
||||
$charData['Filesize'] = round(unpack('l', $data[8])[1] / 1024, 2) . " KB"; // 1.41 KB (1,447 bytes) - checks out
|
||||
// $charData['Checksum'] = bin2hex($data['12']);
|
||||
// $charData['Activeweapon'] = unpack('l', $data['16']);
|
||||
|
||||
$charData['CharacterName'] = ($data[20]);
|
||||
|
||||
$charData['CharacterStatus'] = array_filter(str_split(strtobits($data[36])));
|
||||
|
||||
foreach ($charData['CharacterStatus'] as $k => $v) {
|
||||
$str .= ($characterStatus[$k]) . " ";
|
||||
}
|
||||
|
||||
$charData['CharacterStatus'] = $str;
|
||||
|
||||
// $charData['Characterprogression'] = bindec($data['37']);
|
||||
|
||||
$charData['CharacterClass'] = $sdata->class[unpack('C', $data[40])[1]];
|
||||
|
||||
$charData['CharacterLevel'] = unpack('C', $data[43])[1];
|
||||
|
||||
$charData['Lastplayed'] = gmdate("Y-m-d\TH:i:s\Z", unpack('I', $data[48])[0]);
|
||||
|
||||
// $charData['Assignedskills'] = (unpack('i16', $data['56']));
|
||||
|
||||
$charData['LeftmousebuttonskillID'] = $sdata->skills[unpack('i', $data[120])[1]];
|
||||
$charData['RightmousebuttonskillID'] = $sdata->skills[unpack('i', $data[124])[1]];
|
||||
$charData['LeftswapmousebuttonskillID'] = $sdata->skills[unpack('i', $data[128])[1]];
|
||||
$charData['RightswapmousebuttonskillID'] = $sdata->skills[unpack('i', $data[132])[1]];
|
||||
|
||||
// $charData['Charactermenuappearance'] = unpack('i', $data[136]);
|
||||
|
||||
$x = str_split(strtobits($data[168]), 8);
|
||||
|
||||
$onDifficulty['Norm'] = $x[0][0];
|
||||
$onDifficulty['NM'] = $x[1][0];
|
||||
$onDifficulty['Hell'] = $x[2][0];
|
||||
|
||||
$charData['Difficulty'] = array_filter($onDifficulty);
|
||||
|
||||
//$charData['MapID'] = $data['171'];
|
||||
//$charData['Mercenarydead'] = unpack('i', $data['177']);
|
||||
//$charData['MercenaryID'] = $data['179'];
|
||||
//$charData['MercenaryNameID'] = $data['183'];
|
||||
//$charData['Mercenarytype'] = $data['185'];
|
||||
//$charData['Mercenaryexperience'] = $data['187'];
|
||||
|
||||
|
||||
foreach ($questsNorm as $k => $v) {
|
||||
$x = array_filter(str_split(strtobits($v), 8));
|
||||
if ($x[0][0]) {
|
||||
$quests[] = ($sdata->qNorm[$k] . " => " . $x[0][0]);
|
||||
}
|
||||
}
|
||||
foreach ($questsNM as $k => $v) {
|
||||
$x = array_filter(str_split(strtobits($v), 8));
|
||||
if ($x[0][0]) {
|
||||
$quests[] = ($sdata->qNM[$k] . " => " . $x[0][0]);
|
||||
}
|
||||
}
|
||||
foreach ($questsHell as $k => $v) {
|
||||
$x = array_filter(str_split(strtobits($v), 8));
|
||||
if ($x[0][0]) {
|
||||
$quests[] = ($sdata->qHell[$k] . " => " . $x[0][0]);
|
||||
}
|
||||
}
|
||||
|
||||
$charData['Quests'] = $quests;
|
||||
|
||||
$charData['Waypoints'] = $data[633];
|
||||
$charData['NPCIntroductions'] = $data[714];
|
||||
|
||||
$this->charData[] = $charData;
|
||||
|
||||
// ddump($charData);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return $this->charData;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
230
src/D2SaveFileStructureData.php
Normal file
230
src/D2SaveFileStructureData.php
Normal file
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
|
||||
error_reporting(E_ERROR | E_PARSE);
|
||||
set_time_limit(-1);
|
||||
ini_set('max_input_time', '-1');
|
||||
ini_set('max_execution_time', '0');
|
||||
session_start();
|
||||
ob_start();
|
||||
|
||||
define('DB_FILE', $_SESSION['modname'] . ".db");
|
||||
PDO_Connect("sqlite:" . DB_FILE);
|
||||
|
||||
|
||||
|
||||
|
||||
class D2SaveFileStructureData {
|
||||
|
||||
public $skills;
|
||||
public $class = [
|
||||
0 => 'Amazon',
|
||||
1 => 'Sorceress',
|
||||
2 => 'Necromancer',
|
||||
3 => 'Paladin',
|
||||
4 => 'Barbarian',
|
||||
5 => 'Druid',
|
||||
6 => 'Assassin'
|
||||
];
|
||||
public $characterStatus = [
|
||||
0 => '',
|
||||
1 => '',
|
||||
2 => 'Hardcore',
|
||||
3 => 'Died',
|
||||
4 => '',
|
||||
5 => 'Expansion',
|
||||
6 => 'Ladder',
|
||||
7 => ''
|
||||
];
|
||||
public $offsets = [
|
||||
0 => 4, // Identifier
|
||||
4 => 4, // Version ID
|
||||
8 => 4, // File size
|
||||
12 => 4, // Checksum
|
||||
16 => 4, // Active weapon
|
||||
20 => 16, // Character Name
|
||||
36 => 1, // Character Status
|
||||
37 => 1, // Character progression
|
||||
38 => 2, // Unknown
|
||||
40 => 1, // Character Class
|
||||
41 => 2, // Unknown
|
||||
43 => 1, // Character Level
|
||||
44 => 4, // Unknown
|
||||
48 => 4, // Last played
|
||||
52 => 4, // Unknown
|
||||
56 => 64, // Assigned skills
|
||||
120 => 4, // Left mouse button skill ID
|
||||
124 => 4, // Right mouse button skill ID
|
||||
128 => 4, // Left swap mouse button skill ID
|
||||
132 => 4, // Right swap mouse button skill ID
|
||||
136 => 32, // Character menu appearance
|
||||
168 => 3, // Difficulty
|
||||
171 => 4, // Map ID
|
||||
175 => 2, // Unknown
|
||||
177 => 2, // Mercenary dead
|
||||
179 => 4, // Mercenary ID
|
||||
183 => 2, // Mercenary Name ID
|
||||
185 => 2, // Mercenary type
|
||||
187 => 4, // Mercenary experience
|
||||
191 => 144, // Unknown
|
||||
335 => 298, // Quests
|
||||
633 => 81, // Waypoints
|
||||
714 => 51, // NPC Introductions
|
||||
];
|
||||
public $qNorm = [
|
||||
345 => 'introWarriv',
|
||||
347 => 'DenOfEvil',
|
||||
349 => 'SistersBurialGrounds',
|
||||
351 => 'ToolsOfTheTrade',
|
||||
353 => 'TheSearchForCain',
|
||||
355 => 'TheForgottenTower',
|
||||
357 => 'SistersToTheSlaughter',
|
||||
359 => 'traveledToAct2',
|
||||
361 => 'introJerhyn',
|
||||
363 => 'RadamentsLair',
|
||||
365 => 'TheHoradricStaff',
|
||||
367 => 'TaintedSun',
|
||||
369 => 'ArcaneSanctuary',
|
||||
371 => 'TheSummoner',
|
||||
373 => 'TheSevenTombs',
|
||||
375 => 'traveledToAct3',
|
||||
377 => 'introHratli',
|
||||
379 => 'LamEsensTome',
|
||||
381 => 'KhalimsWill',
|
||||
383 => 'BladeOfTheOldReligion',
|
||||
385 => 'TheGoldenBird',
|
||||
387 => 'TheBlackenedTemple',
|
||||
389 => 'TheGuardian',
|
||||
391 => 'traveledtoAct4',
|
||||
393 => 'introToAct4',
|
||||
395 => 'TheFallenAngel',
|
||||
397 => 'TerrorsEnd',
|
||||
399 => 'HellForge',
|
||||
401 => 'empty',
|
||||
403 => 'empty',
|
||||
405 => 'empty',
|
||||
407 => 'traveledToAct5',
|
||||
409 => 'completedTerrorsEnd',
|
||||
414 => 'SiegeOnHarrogath',
|
||||
416 => 'RescueOnMountArreat',
|
||||
418 => 'PrisonOfIce',
|
||||
420 => 'BetrayalOfHarrogath',
|
||||
422 => 'RiteOfPassage',
|
||||
424 => 'EveOfDestruction',
|
||||
];
|
||||
public $qNM = [
|
||||
438 => 'introWarrivNM',
|
||||
440 => 'DenOfEvilNM',
|
||||
442 => 'SistersBurialGroundsNM',
|
||||
444 => 'ToolsOfTheTradeNM',
|
||||
446 => 'TheSearchForCainNM',
|
||||
448 => 'TheForgottenTowerNM',
|
||||
450 => 'SistersToTheSlaughterNM',
|
||||
452 => 'traveledToAct2NM',
|
||||
454 => 'introJerhynNM',
|
||||
456 => 'RadamentsLairNM',
|
||||
458 => 'TheHoradricStaffNM',
|
||||
460 => 'TaintedSunNM',
|
||||
462 => 'ArcaneSanctuaryNM',
|
||||
464 => 'TheSummonerNM',
|
||||
466 => 'TheSevenTombsNM',
|
||||
468 => 'traveledToAct3NM',
|
||||
470 => 'introHratliNM',
|
||||
472 => 'LamEsensTomeNM',
|
||||
474 => 'KhalimsWillNM',
|
||||
476 => 'BladeOfTheOldReligionNM',
|
||||
478 => 'TheGoldenBirdNM',
|
||||
480 => 'TheBlackenedTempleNM',
|
||||
482 => 'TheGuardianNM',
|
||||
484 => 'traveledtoAct4NM',
|
||||
486 => 'introToAct4NM',
|
||||
488 => 'TheFallenAngelNM',
|
||||
490 => 'TerrorsEndNM',
|
||||
492 => 'HellForgeNM',
|
||||
494 => 'emptyNM',
|
||||
496 => 'emptyNM',
|
||||
498 => 'emptyNM',
|
||||
500 => 'traveledToAct5NM',
|
||||
502 => 'completedTerrorsEndNM',
|
||||
504 => 'SiegeOnHarrogathNM',
|
||||
506 => 'RescueOnMountArreatNM',
|
||||
508 => 'PrisonOfIceNM',
|
||||
510 => 'BetrayalOfHarrogathNM',
|
||||
512 => 'RiteOfPassageNM',
|
||||
514 => 'EveOfDestructionNM',
|
||||
];
|
||||
public $qHell = [
|
||||
528 => 'introWarrivHell',
|
||||
530 => 'DenOfEvilHell',
|
||||
532 => 'SistersBurialGroundsHell',
|
||||
534 => 'ToolsOfTheTradeHell',
|
||||
536 => 'TheSearchForCainHell',
|
||||
538 => 'TheForgottenTowerHell',
|
||||
540 => 'SistersToTheSlaughterHell',
|
||||
542 => 'traveledToAct2Hell',
|
||||
544 => 'introJerhynHell',
|
||||
546 => 'RadamentsLairHell',
|
||||
548 => 'TheHoradricStaffHell',
|
||||
550 => 'TaintedSunHell',
|
||||
552 => 'ArcaneSanctuaryHell',
|
||||
554 => 'TheSummonerHell',
|
||||
556 => 'TheSevenTombsHell',
|
||||
558 => 'traveledToAct3Hell',
|
||||
560 => 'introHratliHell',
|
||||
562 => 'LamEsensTomeHell',
|
||||
564 => 'KhalimsWillHell',
|
||||
566 => 'BladeOfTheOldReligionHell',
|
||||
568 => 'TheGoldenBirdHell',
|
||||
570 => 'TheBlackenedTempleHell',
|
||||
572 => 'TheGuardianHell',
|
||||
574 => 'traveledtoAct4Hell',
|
||||
576 => 'introToAct4Hell',
|
||||
578 => 'TheFallenAngelHell',
|
||||
580 => 'TerrorsEndHell',
|
||||
582 => 'HellForgeHell',
|
||||
584 => 'emptyHell',
|
||||
586 => 'emptyHell',
|
||||
588 => 'emptyHell',
|
||||
590 => 'traveledToAct5Hell',
|
||||
592 => 'completedTerrorsEndHell',
|
||||
594 => 'SiegeOnHarrogathHell',
|
||||
596 => 'RescueOnMountArreatHell',
|
||||
598 => 'PrisonOfIceHell',
|
||||
600 => 'BetrayalOfHarrogathHell',
|
||||
602 => 'RiteOfPassageHell',
|
||||
604 => 'EveOfDestructionHell',
|
||||
];
|
||||
|
||||
public $version = [
|
||||
71 => "1.00 through v1.06",
|
||||
87 => "1.07 or Expansion Set v1.08",
|
||||
89 => "standard game v1.08",
|
||||
92 => "v1.09 (both the standard game and the Expansion Set.)",
|
||||
96 => "v1.10+"
|
||||
];
|
||||
|
||||
/*
|
||||
Initialize Skills From Skills.txt
|
||||
*/
|
||||
|
||||
|
||||
public function __construct() {
|
||||
$sql = "
|
||||
SELECT
|
||||
skills.Id,
|
||||
skills.skilldesc,
|
||||
skilldesc.skilldesc,
|
||||
skilldesc.`str name`,
|
||||
`strings`.`Key`,
|
||||
strings.`String`
|
||||
FROM skills, skilldesc, strings
|
||||
WHERE skills.skilldesc = skilldesc.skilldesc
|
||||
AND skilldesc.`str name` = strings.Key
|
||||
";
|
||||
$res = PDO_FetchAll($sql);
|
||||
|
||||
foreach ($res as $r) {
|
||||
$this->skills[$r['Id']] = $r['String'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
91
src/D2SaveTXT.php
Executable file
91
src/D2SaveTXT.php
Executable file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 2021 Hash Borgir
|
||||
|
||||
This file is part of D2Modder
|
||||
|
||||
Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* This software must not be used for commercial purposes
|
||||
* without my consent. Any sales or commercial use are prohibited
|
||||
* without my express knowledge and consent.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY!
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
class D2SaveTXT {
|
||||
|
||||
public $path;
|
||||
|
||||
public function save($file, $data) {
|
||||
|
||||
$fp = fopen($this->path.DIRECTORY_SEPARATOR.$file, 'a+');
|
||||
$this->saveBackup($file);
|
||||
fputcsv($fp, $data, "\t");
|
||||
}
|
||||
|
||||
|
||||
public function saveBackup($file){
|
||||
|
||||
// if dir doesn't exist, create it
|
||||
if (!is_dir($this->path.DIRECTORY_SEPARATOR."backup")) mkdir($this->path."backup", 0700);
|
||||
|
||||
$oldfile = $this->path.$file;
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
// set new file location to copy to (backup)
|
||||
$newfile = $this->path."\\backup\\$file";
|
||||
} else {
|
||||
$newfile = $this->path."backup/$file";
|
||||
}
|
||||
if (!copy($oldfile, $newfile)) {
|
||||
echo "Failed to create backup of $file...\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function saveTblEnries($filename) {
|
||||
$post = $_POST;
|
||||
|
||||
if (!is_dir($this->path."tblEntries")) mkdir($this->path."tblEntries", 0700);
|
||||
|
||||
// write for .tbl
|
||||
$str = '"'.$post['index'].'"'."\t".'"'.$post['index'].'"'.PHP_EOL;
|
||||
$file = $this->path."\\tblEntries\\$filename";
|
||||
file_put_contents($file, $str, FILE_APPEND);
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
$this->path = TXT_PATH;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
151
src/header.php
151
src/header.php
@@ -18,7 +18,7 @@
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* This software must not be used for commercial purposes
|
||||
* This software must not be used for commercial purposes
|
||||
* without my consent. Any sales or commercial use are prohibited
|
||||
* without my express knowledge and consent.
|
||||
|
||||
@@ -43,80 +43,85 @@
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<?php
|
||||
/* Require the <head> section */
|
||||
require_once "head.php";
|
||||
?>
|
||||
<?php
|
||||
/* Require the <head> section */
|
||||
require_once "head.php";
|
||||
?>
|
||||
|
||||
<body>
|
||||
<div class="container container-top bg_grad">
|
||||
<div style="">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<body>
|
||||
<div class="container container-top bg_grad">
|
||||
<div style="">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
<img src="/img/Diablo2.png" style="float:right"><h1 syle="display:inline; font-weight: 900;"><?php echo $title . " " . $version; ?><span style="font-family: Lato !important; font-size: 14px;"> <?php echo " By" . $author ?></span></h1>
|
||||
<div style="font-family: Lato !important; text-align:right; color: tomato">
|
||||
Active Mod: <span style="color: purple"><?php echo $_SESSION['modname'] ?></span>
|
||||
<span style="color: #8888FF">[<?php echo $_SESSION['path'] ?>]</span>
|
||||
</div>
|
||||
<ul class="nav nav-tabs" id="Tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" id="Unique-tab" data-toggle="tab" href="#Unique" role="tab" aria-controls="Unique" aria-selected="true">Unique Items</a>
|
||||
</li>
|
||||
<!-- <li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Set-tab" data-toggle="tab" href="#Set" role="tab" aria-controls="Set" aria-selected="false">Set Items</a>
|
||||
</li>-->
|
||||
<!-- <li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Gem-tab" data-toggle="tab" href="#Gem" role="tab" aria-controls="Set" aria-selected="false">Gems</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Runewords-tab" data-toggle="tab" href="#Runewords" role="tab" aria-controls="Set" aria-selected="false">Runewords</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Cube-tab" data-toggle="tab" href="#Cube" role="tab" aria-controls="Set" aria-selected="false">Cube</a>
|
||||
</li>
|
||||
-->
|
||||
<img src="/img/Diablo2.png" style="float:right"><h1 syle="display:inline; font-weight: 900;"><?php echo $title . " " . $version; ?><span style="font-family: Lato !important; font-size: 14px;"> <?php echo " By" . $author ?></span></h1>
|
||||
<div style="font-family: Lato !important; text-align:right; color: tomato">
|
||||
Active Mod: <span style="color: purple"><?php echo $_SESSION['modname'] ?></span>
|
||||
<span style="color: #8888FF">[<?php echo $_SESSION['path'] ?>]</span>
|
||||
</div>
|
||||
<ul class="nav nav-tabs" id="Tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" id="Unique-tab" data-toggle="tab" href="#Unique" role="tab" aria-controls="Unique" aria-selected="true">Unique Items</a>
|
||||
</li>
|
||||
<!-- <li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Set-tab" data-toggle="tab" href="#Set" role="tab" aria-controls="Set" aria-selected="false">Set Items</a>
|
||||
</li>-->
|
||||
<!-- <li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Gem-tab" data-toggle="tab" href="#Gem" role="tab" aria-controls="Set" aria-selected="false">Gems</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Runewords-tab" data-toggle="tab" href="#Runewords" role="tab" aria-controls="Set" aria-selected="false">Runewords</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Cube-tab" data-toggle="tab" href="#Cube" role="tab" aria-controls="Set" aria-selected="false">Cube</a>
|
||||
</li>
|
||||
-->
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Chars-tab" data-toggle="tab" href="#Chars" role="tab" aria-controls="Chars" aria-selected="false">Character Editor</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Doc-tab" data-toggle="tab" href="#Doc" role="tab" aria-controls="Doc" aria-selected="false">Documentation Generator</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Doc-tab" data-toggle="tab" href="#Doc" role="tab" aria-controls="Doc" aria-selected="false">Documentation Generator</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Debug-tab" data-toggle="tab" href="#Debug" role="tab" aria-controls="Debug" aria-selected="false">Debug</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="about-tab" data-toggle="tab" href="#About" role="tab" aria-controls="About" aria-selected="false">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-content" id="TabContent">
|
||||
<div class="tab-pane fade show active" id="Unique" role="tabpanel" aria-labelledby="Unique-tab">
|
||||
<?php require_once 'tabs/UniqueItems.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Set" role="tabpanel" aria-labelledby="Set-tab">
|
||||
<?php require_once 'tabs/SetItems.php'; ?>
|
||||
</div>
|
||||
<!-- <div class="tab-pane fade" id="Gem" role="tabpanel" aria-labelledby="Gem-tab">
|
||||
<?php //require_once 'tabs/Gems.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Runewords" role="tabpanel" aria-labelledby="Runewords-tab">
|
||||
<?php //require_once 'tabs/Runewords.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Cube" role="tabpanel" aria-labelledby="Cube-tab">
|
||||
<?php //require_once 'tabs/Cube.php'; ?>
|
||||
</div>-->
|
||||
|
||||
<div class="tab-pane fade" id="Doc" role="tabpanel" aria-labelledby="Doc-tab">
|
||||
<?php require_once 'tabs/Doc.php'; ?>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="Debug" role="tabpanel" aria-labelledby="Debug-tab">
|
||||
<?php require_once 'tabs/Debug.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="About" role="tabpanel" aria-labelledby="about-tab">
|
||||
<?php require_once 'tabs/about.php'; ?>
|
||||
</div>
|
||||
</div>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="Debug-tab" data-toggle="tab" href="#Debug" role="tab" aria-controls="Debug" aria-selected="false">Debug</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="about-tab" data-toggle="tab" href="#About" role="tab" aria-controls="About" aria-selected="false">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-content" id="TabContent">
|
||||
<div class="tab-pane fade show active" id="Unique" role="tabpanel" aria-labelledby="Unique-tab">
|
||||
<?php require_once 'tabs/UniqueItems.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Set" role="tabpanel" aria-labelledby="Set-tab">
|
||||
<?php require_once 'tabs/SetItems.php'; ?>
|
||||
</div>
|
||||
<!-- <div class="tab-pane fade" id="Gem" role="tabpanel" aria-labelledby="Gem-tab">
|
||||
<?php //require_once 'tabs/Gems.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Runewords" role="tabpanel" aria-labelledby="Runewords-tab">
|
||||
<?php //require_once 'tabs/Runewords.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Cube" role="tabpanel" aria-labelledby="Cube-tab">
|
||||
<?php //require_once 'tabs/Cube.php'; ?>
|
||||
</div>-->
|
||||
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Doc" role="tabpanel" aria-labelledby="Doc-tab">
|
||||
<?php require_once 'tabs/Doc.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Chars" role="tabpanel" aria-labelledby="Chars-tab">
|
||||
<?php require_once 'tabs/Chars.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="Debug" role="tabpanel" aria-labelledby="Debug-tab">
|
||||
<?php require_once 'tabs/Debug.php'; ?>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="About" role="tabpanel" aria-labelledby="about-tab">
|
||||
<?php require_once 'tabs/about.php'; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
124
src/tabs/Chars.php
Normal file
124
src/tabs/Chars.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
Copyright (C) 2021 Hash Borgir
|
||||
|
||||
This file is part of D2Modder
|
||||
|
||||
Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* This software must not be used for commercial purposes
|
||||
* without my consent. Any sales or commercial use are prohibited
|
||||
* without my express knowledge and consent.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY!
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
// var_dump($chars->charData);
|
||||
?>
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="text-align: center; margin-top: 20px;">
|
||||
<div class="container">
|
||||
<ul class="nav nav-tabs" id="CTabs" role="tablist">
|
||||
|
||||
|
||||
<?php
|
||||
$tabs = '';
|
||||
foreach ($chars->charData as $c) {
|
||||
|
||||
$tabs .= <<<EOT
|
||||
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link btn btn-outline-danger" style="background: #ddd; border: 1px solid #888;" id="{$c['CharacterName']}-tab" data-toggle="tab" href="#{$c['CharacterName']}" role="tab" aria-controls="{$c['CharacterName']}" aria-selected="true"><img height="64" width="" src="img/chars/{$c['CharacterClass']}.gif">{$c['CharacterName']}</a>
|
||||
</li>
|
||||
EOT;
|
||||
}
|
||||
echo $tabs;
|
||||
?>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="tab-content" id="CTabContent">
|
||||
<?php
|
||||
|
||||
|
||||
foreach ($c['Quests'] as $q) {
|
||||
$quest .= "<>";
|
||||
}
|
||||
|
||||
foreach ($chars->charData as $c) {
|
||||
$tabContent .= <<<EOT
|
||||
<div style="background: white;" class="tab-pane fade" id="{$c['CharacterName']}" role="tabpanel" aria-labelledby="{$c['CharacterName']}-tab">
|
||||
|
||||
<h1 style="margin: 15px;">{$c['CharacterName']}</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<img style="height: 240px;" src="img/chars/{$c['CharacterClass']}.gif">
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>Version: {$c['VersionID']}</li>
|
||||
<li>Filesize: {$c['Filesize']}</li>
|
||||
<li>CharacterStatus: {$c['CharacterStatus']}</li>
|
||||
<li>CharacterClass: {$c['CharacterClass']}</li>
|
||||
<li>CharacterLevel: {$c['CharacterLevel']}</li>
|
||||
<li>Lastplayed: {$c['Lastplayed']}</li>
|
||||
<li>LeftmousebuttonskillID: {$c['LeftmousebuttonskillID']}</li>
|
||||
<li>LeftmousebuttonskillID: {$c['LeftmousebuttonskillID']}</li>
|
||||
<li>LeftswapmousebuttonskillID: {$c['LeftswapmousebuttonskillID']}</li>
|
||||
<li>RightswapmousebuttonskillID: {$c['RightswapmousebuttonskillID']}</li>
|
||||
<li>Difficulty: {$c['Difficulty']}</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>{$c['Quests']}</li>
|
||||
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
EOT;
|
||||
}
|
||||
echo $tabContent;
|
||||
?>
|
||||
|
||||
</div>
|
Reference in New Issue
Block a user