Updated Map Server namespace. Moved all other data folders (www and sql) to data folder. Renamed boot name to Project Meteor.

This commit is contained in:
Filip Maj 2019-06-19 01:10:15 -04:00
parent 18ef69f3d1
commit 91549bff7a
1823 changed files with 102704 additions and 901 deletions

15
Data/www/login/config.php Normal file
View file

@ -0,0 +1,15 @@
<?php
$server_name = "Magis' Funhouse";
$db_server = "localhost";
$db_username = "root";
$db_password = "";
$db_database = "ffxiv_server";
$recaptcha_publickey = "";
$recaptcha_privatekey = "";
if(!defined('FFXIV_SESSION_LENGTH')) define('FFXIV_SESSION_LENGTH', 24); //Session length in hours
?>

View file

@ -0,0 +1,3 @@
.loginBody {
background-color: #EFEFEF;
}

388
Data/www/login/database.php Normal file
View file

@ -0,0 +1,388 @@
<?php
include("config.php");
mysqli_report(MYSQLI_REPORT_STRICT);
function CreateDatabaseConnection($server, $username, $password, $database)
{
try
{
$dataConnection = new mysqli($server, $username, $password);
}
catch(Exception $e)
{
die("Error while connecting to the database");
}
$dataConnection->select_db($database);
$dataConnection->query("SET NAMES 'utf8'");
return $dataConnection;
}
$g_databaseConnection = CreateDatabaseConnection($db_server, $db_username, $db_password, $db_database);
function GenerateRandomSha224()
{
mt_srand(microtime(true) * 100000 + memory_get_usage(true));
return hash("sha224", uniqid(mt_rand(), true));
}
function VerifyUser($dataConnection, $username, $password)
{
$statement = $dataConnection->prepare("SELECT id, passhash, salt FROM users WHERE name = ?");
if(!$statement)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
try
{
$statement->bind_param('s', $username);
if(!$statement->execute())
{
throw new Exception(__FUNCTION__ . " failed.");
}
$statement->bind_result($id, $storedPasshash, $salt);
if(!$statement->fetch())
{
throw new Exception("Incorrect username.");
}
$saltedPassword = $password . $salt;
$hashedPassword = hash("sha224", $saltedPassword);
if($hashedPassword !== $storedPasshash)
{
throw new Exception("Incorrect password.");
}
return $id;
}
finally
{
$statement->close();
}
}
function InsertUser($dataConnection, $username, $passhash, $salt, $email)
{
{
$statement = $dataConnection->prepare("INSERT INTO users (name, passhash, salt, email) VALUES (?, ?, ?, ?)");
if(!$statement)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
try
{
$statement->bind_param('ssss', $username, $passhash, $salt, $email);
if(!$statement->execute())
{
throw new Exception(__FUNCTION__ . " failed.");
}
}
finally
{
$statement->close();
}
}
}
function RefreshOrCreateSession($dataConnection, $userId)
{
try
{
$sessionId = GetSessionFromUserId($dataConnection, $userId);
RefreshSession($dataConnection, $sessionId);
}
catch(Exception $e)
{
$sessionId = CreateSession($dataConnection, $userId);
}
return $sessionId;
}
function CreateSession($dataConnection, $userId)
{
//Delete any session that might be active
{
$statement = $dataConnection->prepare("DELETE FROM sessions WHERE userId = ?");
if(!$statement)
{
throw new Exception("Failed to create session: " . $dataConnection->error);
}
try
{
$statement->bind_param('i', $userId);
if(!$statement->execute())
{
throw new Exception("Failed to create session: " . $dataConnection->error);
}
}
finally
{
$statement->close();
}
}
//Create new session
{
$sessionId = GenerateRandomSha224();
$statement = $dataConnection->prepare("INSERT INTO sessions (id, userid, expiration) VALUES (?, ?, NOW() + INTERVAL " . FFXIV_SESSION_LENGTH . " HOUR)");
if(!$statement)
{
throw new Exception("Failed to create session: " . $dataConnection->error);
}
try
{
$statement->bind_param('si', $sessionId, $userId);
if(!$statement->execute())
{
throw new Exception("Failed to create session: " . $dataConnection->error);
}
}
finally
{
$statement->close();
}
return $sessionId;
}
}
function GetSessionFromUserId($dataConnection, $userId)
{
$statement = $dataConnection->prepare("SELECT id FROM sessions WHERE userId = ? AND expiration > NOW()");
if(!$statement)
{
throw new Exception("Failed to get session id: " . $dataConnection->error);
}
try
{
$statement->bind_param('i', $userId);
if(!$statement->execute())
{
throw new Exception("Failed to get session id: " . $dataConnection->error);
}
$statement->bind_result($sessionId);
if(!$statement->fetch())
{
throw new Exception("Failed to get session id: " . $dataConnection->error);
}
return $sessionId;
}
finally
{
$statement->close();
}
}
function RefreshSession($dataConnection, $sessionId)
{
$statement = $dataConnection->prepare("UPDATE sessions SET expiration = NOW() + INTERVAL " . FFXIV_SESSION_LENGTH . " HOUR WHERE id = ?");
if(!$statement)
{
throw new Exception("Failed to refresh session: " . $dataConnection->error);
}
try
{
$statement->bind_param('s', $sessionId);
if(!$statement->execute())
{
throw new Exception("Failed to refresh session: " . $dataConnection->error);
}
}
finally
{
$statement->close();
}
}
function GetUserIdFromSession($dataConnection, $sessionId)
{
$statement = $dataConnection->prepare("SELECT userId FROM sessions WHERE id = ? AND expiration > NOW()");
if(!$statement)
{
throw new Exception("Could not get user id.");
}
try
{
$statement->bind_param('s', $sessionId);
if(!$statement->execute())
{
throw new Exception("Could not get user id.");
}
$statement->bind_result($userId);
if(!$statement->fetch())
{
throw new Exception("Could not get user id.");
}
return $userId;
}
finally
{
$statement->close();
}
}
function GetUserInfo($dataConnection, $userId)
{
$statement = $dataConnection->prepare("SELECT name FROM users WHERE id = ?");
if(!$statement)
{
throw new Exception("Failed to get user information: " . $dataConnection->error);
}
try
{
$statement->bind_param('i', $userId);
if(!$statement->execute())
{
throw new Exception("Failed to get user information: " . $dataConnection->error);
}
$result = $statement->get_result();
if(!$result)
{
throw new Exception("Failed to get user information: " . $dataConnection->error);
}
$row = $result->fetch_assoc();
if(!$row)
{
throw new Exception("Failed to get user information: " . $dataConnection->error);
}
return $row;
}
finally
{
$statement->close();
}
}
function GetUserCharacters($dataConnection, $userId)
{
$statement = $dataConnection->prepare("SELECT id, name FROM characters WHERE userId = ?");
if(!$statement)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
try
{
$statement->bind_param('i', $userId);
if(!$statement->execute())
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$result = $statement->get_result();
if(!$result)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$characters = array();
while(1)
{
$row = $result->fetch_assoc();
if(!$row)
{
break;
}
array_push($characters, $row);
}
return $characters;
}
finally
{
$statement->close();
}
}
function GetCharacterInfo($dataConnection, $userId, $characterId)
{
$query = sprintf("SELECT * FROM characters WHERE userId = '%d' AND id = '%d'",
$userId, $characterId);
$result = $dataConnection->query($query);
if(!$result)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$row = $result->fetch_assoc();
if(!$row)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
return $row;
}
function UpdateCharacterInfo($dataConnection, $characterId, $characterInfo)
{
$statement = $dataConnection->prepare("UPDATE ffxiv_characters SET
name = ?, tribe = ?, size = ?, voice = ?, skinColor = ?, hairStyle = ?, hairColor = ?, hairOption = ?,
eyeColor = ?, faceType = ?, faceBrow = ?, faceEye = ?, faceIris = ?, faceNose = ?, faceMouth = ?, faceJaw = ?,
faceCheek = ?, faceOption1 = ?, faceOption2 = ?, guardian = ?, birthMonth = ?, birthDay = ?, allegiance = ?,
weapon1 = ?, weapon2 = ?, headGear = ?, bodyGear = ?, legsGear = ?, handsGear = ?, feetGear = ?,
waistGear = ?, rightEarGear = ?, leftEarGear = ?, rightFingerGear = ?, leftFingerGear = ?
WHERE id = ?");
if(!$statement)
{
throw new Exception("Failed to update character information: " . $dataConnection->error);
}
try
{
if(!$statement->bind_param("siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
$characterInfo["name"], $characterInfo["tribe"], $characterInfo["size"], $characterInfo["voice"],
$characterInfo["skinColor"], $characterInfo["hairStyle"], $characterInfo["hairColor"],
$characterInfo["hairOption"], $characterInfo["eyeColor"], $characterInfo["faceType"],
$characterInfo["faceBrow"], $characterInfo["faceEye"], $characterInfo["faceIris"],
$characterInfo["faceNose"], $characterInfo["faceMouth"], $characterInfo["faceJaw"],
$characterInfo["faceCheek"], $characterInfo["faceOption1"], $characterInfo["faceOption2"],
$characterInfo["guardian"], $characterInfo["birthMonth"], $characterInfo["birthDay"], $characterInfo["allegiance"],
$characterInfo["weapon1"], $characterInfo["weapon2"], $characterInfo["headGear"], $characterInfo["bodyGear"],
$characterInfo["legsGear"], $characterInfo["handsGear"], $characterInfo["feetGear"],
$characterInfo["waistGear"], $characterInfo["rightEarGear"], $characterInfo["leftEarGear"],
$characterInfo["rightFingerGear"], $characterInfo["leftFingerGear"],
$characterId))
{
throw new Exception("Failed to update character information: " . $dataConnection->error);
}
if(!$statement->execute())
{
throw new Exception("Failed to update character information: " . $dataConnection->error);
}
}
finally
{
$statement->close();
}
}
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
Data/www/login/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

151
Data/www/login/index.php Normal file
View file

@ -0,0 +1,151 @@
<?php
error_reporting(E_ALL | E_STRICT);
include("config.php");
include("database.php");
$loginError = "";
function doLogin($dataConnection)
{
$username = trim($_POST["username"]);
$password = trim($_POST["password"]);
if(empty($username))
{
throw new Exception("You must enter an username.");
}
if(empty($password))
{
throw new Exception("You must enter a password.");
}
$userId = VerifyUser($dataConnection, $username, $password);
return RefreshOrCreateSession($dataConnection, $userId);
}
$loginError = "";
$currentTimeUTC = time();
if(isset($_POST["login"]))
{
try
{
$sessionId = doLogin($g_databaseConnection);
}
catch(Exception $e)
{
$loginError = $e->getMessage();
}
}
?>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
<style>
html, body {
font-family: Arial;
font-size: 14px;
margin:0;
padding: 0;
width: 600px;
}
html {
padding: 10px;
}
form {
background-color: #eee;
border: solid 1px #666;
border-radius: 3px;
margin-bottom: 0;
}
table {
justify-content: center;
width: 100%;
height: 100%;
padding: 20px;
}
form input {
width: 100%;
border: solid 1px #222;
padding: 3px;
outline: none;
}
form button {
background-image: url(img/btLogin.gif);
background-position: 0 0;
background-repeat: no-repeat;
border: none;
width: 200px;
height: 40px;
}
form button:hover {
background-position: 0 -40px;
cursor: pointer;
}
.errorText{
color: red;
}
.banner {
margin-top: 10px;
}
</style>
</head>
<body>
<?php if (isset($sessionId)) echo("<x-sqexauth sid=\"$sessionId\" lang=\"en-us\" region=\"2\" utc=\"$currentTimeUTC\" />"); ?>
<table border="0" cellpadding="0" cellspacing="0">
<tbody><tr>
<td width="50%">
<img src="img/logo.png" class="logo" width="300px">
</td>
<td width="50%">
<form method="post">
<table border="0" cellpadding="5px" cellspacing="0">
<tbody><tr>
<td width="5%"><img src="img/lbSQEXId_mem.gif"></td>
<td width="40%"><label for="username">Username</label></td>
<td width="50%"><input id="username" name="username" autocomplete="off" type="text"></td>
</tr>
<tr>
<td><img src="img/lbSQEXPass_mem.gif" <="" td="">
</td><td><label for="password">Password</label></td>
<td><input id="password" name="password" autocomplete="off" type="password"></td>
</tr>
<tr>
<td colspan="3" align="center">
<p class=errorText><?php echo($loginError) ?></p>
</td>
</tr>
<tr>
<td colspan="3" align="center">
<button type="submit" name="login">&nbsp;</button>
</td>
</tr>
<tr>
<td colspan="3" align="center">
<a href="..\login_su\create_user.php">Don't have a awesome account?</a>
</td>
</tr>
</tbody></table>
</form></td>
</tr>
<tr>
<td colspan="2" align="center">
<img src="img/banner.png" class="banner" width="720px">
</td>
</tr>
</tbody></table>
</body></html>

View file

@ -0,0 +1,13 @@
<?php
$db_server = "localhost";
$db_username = "root";
$db_password = "";
$db_database = "ffxiv_server";
$recaptcha_publickey = "";
$recaptcha_privatekey = "";
if(!defined('FFXIV_SESSION_LENGTH')) define('FFXIV_SESSION_LENGTH', 24); //Session length in hours
?>

View file

@ -0,0 +1,50 @@
<?php
error_reporting(E_ALL | E_STRICT);
include("config.php");
include("database.php");
include("control_panel_common.php");
$g_userCharacters = GetUserCharacters($g_databaseConnection, $g_userId);
?>
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Seventh Umbral Server</title>
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/global.css" />
</head>
<body>
<?php include("control_panel_header.php"); ?>
<p>
<div class="edit">
<h2>Characters</h2>
<br />
<table class="editForm">
<tr>
<th>Name</th>
<th>Action</th>
</tr>
<?php
foreach($g_userCharacters as $character)
{
?>
<tr>
<td><?php echo $character["name"]; ?></td>
<td>
<a href="control_panel_edit_character.php?id=<?php echo $character["id"]; ?>">
Edit
</a>
</td>
</tr>
<?php
}
?>
</table>
</p>
</body>
</html>

View file

@ -0,0 +1,20 @@
<?php
if(!isset($_COOKIE["sessionId"]))
{
header("Location: control_panel_login.php");
exit;
}
$g_sessionId = $_COOKIE["sessionId"];
try
{
$g_userId = GetUserIdFromSession($g_databaseConnection, $g_sessionId);
}
catch(Exception $e)
{
header("Location: control_panel_login.php");
exit;
}
?>

View file

@ -0,0 +1,754 @@
<?php
error_reporting(E_ALL | E_STRICT);
include("config.php");
include("database.php");
include("control_panel_common.php");
if(!isset($_GET["id"]))
{
header("Location: control_panel.php");
exit;
}
$g_characterId = $_GET["id"];
$g_tribes = array(
1 => "Hyur Midlander Male",
2 => "Hyur Midlander Female",
3 => "Hyur Highlander Male",
4 => "Elezen Wildwood Male",
5 => "Elezen Wildwood Female",
6 => "Elezen Duskwight Male",
7 => "Elezen Duskwight Female",
8 => "Lalafell Plainsfolk Male",
9 => "Lalafell Plainsfolk Female",
10 => "Lalafell Dunesfolk Male",
11 => "Lalafell Dunesfolk Female",
12 => "Miqo'te Seeker of the Sun Female",
13 => "Miqo'te Keeper of the Moon Female",
14 => "Roegadyn Sea Wolf Male",
15 => "Roegadyn Hellsguard Male"
);
$g_guardians = array(
1 => "Halone, the Fury",
2 => "Menphina, the Lover",
3 => "Thaliak, the Scholar",
4 => "Nymeia, the Spinner",
5 => "Llymlaen, the Navigator",
6 => "Oschon, the Wanderer",
7 => "Byregot, the Builder",
8 => "Rhalgr, the Destroyer",
9 => "Azeyma, the Warden",
10 => "Nald'thal, the Traders",
11 => "Nophica, the Matron",
12 => "Althyk, the Keeper"
);
$g_allegiances = array(
1 => "Limsa Lominsa",
2 => "Gridania",
3 => "Ul'dah",
);
/*
$g_htmlToDbFieldMapping = array(
"characterName" => "name",
"characterTribe" => "tribe",
"characterSize" => "size",
"characterVoice" => "voice",
"characterSkinColor" => "skinColor",
"characterHairStyle" => "hairStyle",
"characterHairColor" => "hairColor",
"characterHairOption" => "hairVariation",
"characterEyeColor" => "eyeColor",
"characterFaceType" => "faceType",
"characterFaceBrow" => "faceEyebrows",
"characterFaceEye" => "faceEyeShape",
"characterFaceIris" => "faceIrisSize",
"characterFaceNose" => "faceNose",
"characterFaceMouth" => "faceMouth",
"characterFaceJaw" => "faceJaw",
"characterFaceCheek" => "faceCheek",
"characterFaceOption1" => "faceOption1",
"characterFaceOption2" => "faceOption2",
"characterGuardian" => "guardian",
"characterBirthMonth" => "birthMonth",
"characterBirthDay" => "birthDay",
"characterAllegiance" => "initialTown",
"characterWeapon1" => "weapon1",
"characterWeapon2" => "weapon2",
"characterHeadGear" => "headGear",
"characterBodyGear" => "bodyGear",
"characterLegsGear" => "legsGear",
"characterHandsGear" => "handsGear",
"characterFeetGear" => "feetGear",
"characterWaistGear" => "waistGear",
"characterRightEarGear" => "rightEarGear",
"characterLeftEarGear" => "leftEarGear",
"characterRightFingerGear" => "rightFingerGear",
"characterLeftFingerGear" => "leftFingerGear"
);
*/
$g_height = array(
0 => "Shortest",
1 => "Short",
2 => "Average",
3 => "Tall",
4 => "Tallest"
);
$g_yesno = array(
0 => "No",
1 => "Yes"
);
$g_grandcompany = array(
0 => "None",
/* TODO: Find correct order for 1+ */
1 => "Maelstrom",
2 => "Order of the Twin Adder ",
3 => "Immortal Flames"
);
$g_profileMapping = array(
"characterName" => "name",
"characterCreationDate" => "creationDate",
"characterIsLegacy" => "isLegacy",
"characterPlayTime" => "playTime",
/*
"characterPositionX" => "positionX",
"characterPositionY" => "positionY",
"characterPositionZ" => "positionZ",
"characterPositionR" => "rotation",
"characterCurrentZoneId" => "currentZoneId",
*/
"characterGuardian" => "guardian",
"characterBirthDay" => "birthDay",
"characterBirthMonth" => "birthMonth",
"characterAllegiance" => "initialTown",
"characterTribe" => "tribe",
"characterGcCurrent" => "gcCurrent",
"characterGcLimsaRank" => "gcLimsaRank",
"characterGcGridaniaRank" => "gcGridaniaRank",
"characterGcUldahRank" => "gcUldahRank",
/*
"characterCurrentTitle" => "currentTitle",
"characterRestBonus" => "restBonus",
*/
"characterAchievementPoints" => "achievementPoints",
);
$g_appearanceMapping = array(
/*
"characterBaseId" => "baseId", // Basic appearance?
*/
"characterSize" => "size",
"characterVoice" => "voice",
"characterSkinColor" => "skinColor",
"characterHairStyle" => "hairStyle",
"characterHairColor" => "hairColor",
"characterHairHighlightColor" => "hairHighlightColor",
"characterHairVariation" => "hairVariation",
"characterEyeColor" => "eyeColor",
"characterFaceType" => "faceType",
"characterFaceBrow" => "faceEyebrows",
"characterFaceEye" => "faceEyeShape",
"characterFaceIris" => "faceIrisSize",
"characterFaceNose" => "faceNose",
"characterFaceMouth" => "faceMouth",
"characterFaceFeatures" => "faceFeatures",
"characterFaceEars" => "ears",
"characterFaceCharacteristics" => "characteristics",
"characterFaceCharacteristicsColor" => "characteristicsColor"
);
$g_chocoboMapping = array(
"characterHasChocobo" => "hasChocobo",
"characterHasGoobbue" => "hasGoobbue",
"characterChocoboAppearance" => "chocoboAppearance",
"characterChocoboName" => "chocoboName"
);
$g_classLevels = array(
"characterGla" => "gla",
"characterPug" => "pug",
"characterMrd" => "mrd",
"characterLnc" => "lnc",
"characterArc" => "arc",
"characterCnj" => "cnj",
"characterThm" => "thm",
"characterCrp" => "crp",
"characterBsm" => "bsm",
"characterArm" => "arm",
"characterGsm" => "gsm",
"characterLtw" => "ltw",
"characterWvr" => "wvr",
"characterAlc" => "alc",
"characterCul" => "cul",
"characterMin" => "min",
"characterBtn" => "btn",
"characterFsh" => "fsh"
);
function SaveCharacter($databaseConnection, $htmlFieldMapping, $characterId)
{
$characterInfo = array();
foreach($htmlFieldMapping as $htmlFieldName => $dbFieldName)
{
$characterInfo[$dbFieldName] = $_POST[$htmlFieldName];
}
UpdateCharacterInfo($databaseConnection, $characterId, $characterInfo);
}
function GenerateTextField($characterInfo, $htmlFieldMapping, $htmlFieldName, $fieldMaxLength = null)
{
$inputMaxLength = ($fieldMaxLength === null) ? "" : sprintf("maxlength=\"%d\"", $fieldMaxLength);
return sprintf("<input id=\"%s\" name=\"%s\" type=\"text\" value=\"%s\" %s readonly=\"readonly\" />",
$htmlFieldName, $htmlFieldName, $characterInfo[$htmlFieldMapping[$htmlFieldName]], $inputMaxLength);
}
function GenerateSelectField($characterInfo, $htmlFieldMapping, $htmlFieldOptions, $htmlFieldName)
{
$dbFieldName = $htmlFieldMapping[$htmlFieldName];
$htmlText = sprintf("<select id=\"%s\" name=\"%s\">\n",
$htmlFieldName, $htmlFieldName);
foreach($htmlFieldOptions as $optionId => $optionName)
{
$htmlText .= sprintf("<option value=\"%d\" %s>%s</option>\n",
$optionId,
($optionId === (int)$characterInfo[$dbFieldName]) ? "selected" : "",
$optionName);
}
$htmlText .= "</select>\n";
return $htmlText;
}
if(isset($_POST["cancel"]))
{
header("Location: control_panel.php");
exit;
}
if(isset($_POST["save"]))
{
SaveCharacter($g_databaseConnection, $g_htmlToDbFieldMapping, $g_characterId);
header("Location: control_panel.php");
exit;
}
try
{
$g_characterInfo = GetCharacterInfo($g_databaseConnection, $g_userId, $g_characterId);
$g_characterAppearance = GetCharacterAppearance($g_databaseConnection, $g_userId, $g_characterId);
/* $g_characterChocobo = GetCharacterChocobo($g_databaseConnection, $g_userId, $g_characterId); */
$g_characterClassLevels = GetCharacterClassLevels($g_databaseConnection, $g_userId, $g_characterId);
}
catch(Exception $e)
{
header("Location: control_panel.php");
exit;
}
?>
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Character Info</title>
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/global.css" />
<script type="application/ecmascript">
var weaponPresets = <?php echo require_once("presets_weapon.json"); ?>;
var armorPresets = <?php echo require_once("presets_armor.json"); ?>;
function loadPresetsInSelect(presets, selectName)
{
var select = document.getElementById(selectName);
for(var presetId in presets)
{
var el = document.createElement("option");
var preset = presets[presetId];
el.textContent = preset.name;
el.value = presetId;
select.appendChild(el);
}
}
window.onload = function()
{
loadPresetsInSelect(weaponPresets, "weaponPresets");
loadPresetsInSelect(armorPresets, "armorPresets");
}
function byteArrayToString(byteArray)
{
var i, str = '';
for(i = 0; i < byteArray.length; i++)
{
str += String.fromCharCode(byteArray[i]);
}
return str;
}
function decodeCharacterFile(inputArrayBuffer)
{
var outputArrayBuffer = new ArrayBuffer(inputArrayBuffer.byteLength);
var inputDataView = new DataView(inputArrayBuffer);
var outputDataView = new DataView(outputArrayBuffer);
for(var i = 0; i < inputDataView.byteLength; i++)
{
outputDataView.setUint8(i, inputDataView.getUint8(i) ^ 0x73);
}
return outputArrayBuffer;
}
function getCharacterAttributesFromString(characterFileString)
{
var lineArray = characterFileString.split('\n');
lineArray = lineArray.filter(function(str) { return str != ''; });
var characterAttributes = [];
for(var i = 0; i < lineArray.length; i++)
{
var attributeLine = lineArray[i];
attributeItems = attributeLine.split(',');
characterAttributes.push(
{
"name" : attributeItems[0].trim(),
"value" : attributeItems[3].trim()
}
);
}
return characterAttributes;
}
function getCharacterAttributeValue(attributes, attributeName)
{
for(var i = 0; i < attributes.length; i++)
{
var attribute = attributes[i];
if(attribute.name === attributeName)
{
return attribute.value;
}
}
return undefined;
}
function onImportAppearanceFileReaderLoad(evt)
{
var decodedCharacterFileArray = decodeCharacterFile(evt.target.result);
var decodedCharacterFileString = byteArrayToString(new Uint8Array(decodedCharacterFileArray));
var characterAttributes = getCharacterAttributesFromString(decodedCharacterFileString);
var fieldAssociations =
[
[ 'characterSize', 'appearancetype_size' ],
[ 'characterVoice', 'appearancetype_voice' ],
[ 'characterSkinColor', 'appearancetype_skin' ],
[ 'characterHairStyle', 'appearancetype_hairstyle' ],
[ 'characterHairColor', 'appearancetype_haircolor' ],
[ 'characterHairOption', 'appearancetype_hairoption2' ],
[ 'characterEyeColor', 'appearancetype_eyecolor' ],
[ 'characterFaceType', 'appearancetype_facetype' ],
[ 'characterFaceBrow', 'appearancetype_facebrow' ],
[ 'characterFaceEye', 'appearancetype_faceeye' ],
[ 'characterFaceIris', 'appearancetype_faceiris' ],
[ 'characterFaceNose', 'appearancetype_facenose' ],
[ 'characterFaceMouth', 'appearancetype_facemouth' ],
[ 'characterFaceJaw', 'appearancetype_facejaw_special' ],
[ 'characterFaceCheek', 'appearancetype_facecheek' ],
[ 'characterFaceOption1', 'appearancetype_faceoption1' ],
[ 'characterFaceOption2', 'appearancetype_faceoption2' ],
];
var characterTribe = getCharacterAttributeValue(characterAttributes, "rsc_tribe");
var characterTribeSelect = document.getElementById('characterTribe');
for(var i = 0; i < characterTribeSelect.length; i++)
{
var characterTribeSelectItem = characterTribeSelect[i];
characterTribeSelectItem.selected = characterTribeSelectItem.value === characterTribe;
}
for(var i = 0; i < fieldAssociations.length; i++)
{
var fieldAssociation = fieldAssociations[i];
var attributeValue = getCharacterAttributeValue(characterAttributes, fieldAssociation[1]);
document.getElementById(fieldAssociation[0]).value = attributeValue;
}
}
function importAppearanceFromFile(evt)
{
var file = evt.target.files[0];
var fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = onImportAppearanceFileReaderLoad;
}
function onEquipWeaponPreset()
{
var select = document.getElementById("weaponPresets");
var weapon1Field = document.getElementById("characterWeapon1");
var weapon2Field = document.getElementById("characterWeapon2");
var preset = weaponPresets[select.value];
weapon1Field.value = preset.weapon1;
weapon2Field.value = preset.weapon2;
}
function onEquipArmorPreset()
{
var select = document.getElementById("armorPresets");
var headGearField = document.getElementById("characterHeadGear");
var bodyGearField = document.getElementById("characterBodyGear");
var legsGearField = document.getElementById("characterLegsGear");
var handsGearField = document.getElementById("characterHandsGear");
var feetGearField = document.getElementById("characterFeetGear");
var waistGearField = document.getElementById("characterWaistGear");
var preset = armorPresets[select.value];
headGearField.value = preset.headGear;
bodyGearField.value = preset.bodyGear;
legsGearField.value = preset.legsGear;
handsGearField.value = preset.handsGear;
feetGearField.value = preset.feetGear;
waistGearField.value = preset.waistGear;
}
function toggleDisplay(elementName)
{
var element = document.getElementById(elementName);
if(element.style.display === 'none')
{
element.style.display = '';
}
else
{
element.style.display = 'none';
}
}
</script>
</head>
<body>
<?php include("header.php"); ?>
<?php include("control_panel_header.php"); ?>
<div class="edit">
<h2>Character Info (<a href="#" onclick="toggleDisplay('guideDiv');">Help</a>)</h2>
<div id="guideDiv" style="background-color: white; display: none;">
<h3>Character Appearance Notes:</h3>
<p style="text-align: left">
Any value that is a bare number without any other description before or after it does
not correlate to the values selected in the ingame character creator.
</p>
<!--
<p style="text-align: left">
All values here are editable, so change them at your own risk. Just keep in mind that
you can always import an appearance from a character creation data file and equip presetted
equipment to reset your character.
</p>
<h3>Import Appearance</h3>
<p style="text-align: left">
Use this to import a character creation data file. Those files
are created by the client when saving character creation data in the character creation
mode, just before selecting the server on which the character will be created. They are usually
located in the "C:\Users\{Username}\Documents\My Games\FINAL FANTASY XIV\user\00000000" folder
and have a '.CMB' extension.
</p>
-->
</div>
<br />
<form method="post" autocomplete="off">
<table class="editForm">
<tr>
<th colspan="4">Profile</th>
</tr>
<tr>
<td>Name:</td>
<td>Legacy Character:</td>
<td>Creation Date:</td>
<td>Play Time:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterInfo, $g_profileMapping, "characterName", 20); ?></td>
<td><?php echo GenerateSelectField($g_characterInfo, $g_profileMapping, $g_yesno, "characterIsLegacy"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_profileMapping, "characterCreationDate", 20); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_profileMapping, "characterPlayTime"); ?></td>
</tr>
<tr>
<td>Guardian:</td>
<td>Birth Month:</td>
<td>Birth Day:</td>
<td>Allegiance:</td>
</tr>
<tr>
<td><?php echo GenerateSelectField($g_characterInfo, $g_profileMapping, $g_guardians, "characterGuardian"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_profileMapping, "characterBirthMonth"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_profileMapping, "characterBirthDay"); ?></td>
<td><?php echo GenerateSelectField($g_characterInfo, $g_profileMapping, $g_allegiances, "characterAllegiance"); ?></td>
</tr>
<tr>
<td>Current GC:</td>
<td>Maelstrom Rank:</td>
<td>Twin Adder Rank:</td>
<td>Immortal Flame Rank:</td>
</tr>
<tr>
<td><?php echo GenerateSelectField($g_characterInfo, $g_profileMapping, $g_grandcompany, "characterGcCurrent"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_profileMapping, "characterGcLimsaRank"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_profileMapping, "characterGcGridaniaRank"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_profileMapping, "characterGcUldahRank"); ?></td>
</tr>
<!--
<tr>
<td>Chocobo Unlocked:</td>
<td>Goobbue Unlocked:</td>
<td>Chocobo Appearance:</td>
<td>Chocobo Name:</td>
</tr>
<tr>
<td><?php echo GenerateSelectField($g_characterChocobo, $g_chocoboMapping, $g_yesno, "characterHasChocobo"); ?></td>
<td><?php echo GenerateSelectField($g_characterChocobo, $g_chocoboMapping, $g_yesno, "characterHasGoobbue"); ?></td>
<td><?php echo GenerateTextField($g_characterChocobo, $g_chocoboMapping, "characterChocoboAppearance"); ?></td>
<td><?php echo GenerateTextField($g_characterChocobo, $g_chocoboMapping, "characterChocoboName"); ?></td>
</tr>
-->
<tr>
<td>GLA:</td>
<td>PUG:</td>
<td>MRD:</td>
<td>LNC:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterGla"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterPug"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterMrd"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterLnc"); ?></td>
</tr>
<tr>
<td>ARC:</td>
<td>CNJ:</td>
<td>THM:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterArc"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterCnj"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterThm"); ?></td>
</tr>
<tr>
<td>CRP:</td>
<td>BSM:</td>
<td>ARM:</td>
<td>GSM:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterCrp"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterBsm"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterArm"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterGsm"); ?></td>
</tr>
<tr>
<td>LTW:</td>
<td>WVR:</td>
<td>ALC:</td>
<td>CUL:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterLtw"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterWvr"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterAlc"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterCul"); ?></td>
</tr>
<tr>
<td>MIN:</td>
<td>BTN:</td>
<td>FSH:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterMin"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterBtn"); ?></td>
<td><?php echo GenerateTextField($g_characterClassLevels, $g_classLevels, "characterFsh"); ?></td>
</tr>
</table>
<br />
<hr />
<table class="editForm">
<tr>
<th colspan="5">Appearance</th>
</tr>
<tr>
<td colspan="2">Race/Tribe:</td>
<td>Height:</td>
<td>Voice:</td>
<td>Skin Tone:</td>
</tr>
<tr>
<td colspan="2"><?php echo GenerateSelectField($g_characterInfo, $g_profileMapping, $g_tribes, "characterTribe"); ?></td>
<td><?php echo GenerateSelectField($g_characterAppearance, $g_appearanceMapping, $g_height, "characterSize"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterVoice"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterSkinColor"); ?></td>
</tr>
<tr>
<td>Hairstyle:</td>
<td>Variation:</td>
<td>Hair Color:</td>
<td>Highlights:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterHairStyle"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterHairVariation"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterHairColor"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterHairHighlightColor"); ?></td>
</tr>
<tr>
<td>Face Type:</td>
<td>Eyebrows:</td>
<td>Eye Shape:</td>
<td>Iris Size:</td>
</tr>
<tr>
<td>Eye Color:</td>
<td>Nose:</td>
<td>Face Mouth:</td>
<td>Features:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceType"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceBrow"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceEye"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceIris"); ?></td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterEyeColor"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceNose"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceMouth"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceFeatures"); ?></td>
</tr>
<tr>
<td>Characteristic:</td>
<td>Color:</td>
<td>Ears:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceCharacteristics"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceCharacteristicsColor"); ?></td>
<td><?php echo GenerateTextField($g_characterAppearance, $g_appearanceMapping, "characterFaceEars"); ?></td>
</tr>
<!--
<tr>
<td></td>
</tr>
<tr>
<td>
<script>
function onImportAppearanceButtonClick()
{
document.getElementById('importAppearance').click();
}
</script>
<input type="file" id="importAppearance" style="display: none;">
<button onclick="onImportAppearanceButtonClick(); return false;">Import Appearance</button>
<script>
document.getElementById('importAppearance').addEventListener('change', importAppearanceFromFile, false);
</script>
</td>
</tr>
-->
</table>
<br />
<hr />
<!--
<table class="editForm">
<tr>
<th colspan="4">Gear</th>
</tr>
<tr>
<td>Weapon 1:</td>
<td>Weapon 2:</td>
<td></td>
<td></td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterWeapon1"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterWeapon2"); ?></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Head Gear:</td>
<td>Body Gear:</td>
<td>Legs Gear:</td>
<td>Hands Gear:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterHeadGear"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterBodyGear"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterLegsGear"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterHandsGear"); ?></td>
</tr>
<tr>
<td>Feet Gear:</td>
<td>Waist Gear:</td>
<td></td>
<td></td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterFeetGear"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterWaistGear"); ?></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Right Ear Gear:</td>
<td>Left Ear Gear:</td>
<td>Right Finger Gear:</td>
<td>Left Finger Gear:</td>
</tr>
<tr>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterRightEarGear"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterLeftEarGear"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterRightFingerGear"); ?></td>
<td><?php echo GenerateTextField($g_characterInfo, $g_htmlToDbFieldMapping, "characterLeftFingerGear"); ?></td>
</tr>
<tr>
<td colspan="2">Weapon Presets:</td>
<td colspan="2">Armor Presets:</td>
</tr>
<tr>
<td colspan="2">
<select id="weaponPresets"></select>
<button onclick="onEquipWeaponPreset(); return false;">Equip</button>
</td>
<td colspan="2">
<select id="armorPresets"></select>
<button onclick="onEquipArmorPreset(); return false;">Equip</button>
</td>
</tr>
</table>
<br />
<hr />
-->
<!--
<table class="infoForm">
<tr>
<td>
<input type="submit" name="save" value="Save" />
<input type="submit" name="cancel" value="Cancel" />
</td>
</tr>
</table>
-->
</form>
</div>
<div>
</div>
</body>
</html>

View file

@ -0,0 +1,8 @@
<?php
$g_userInfo = GetUserInfo($g_databaseConnection, $g_userId);
?>
<p>
Welcome, <?php echo($g_userInfo["name"]); ?>. <a href="control_panel_logout.php">(Logout)</a>
</p>

View file

@ -0,0 +1,81 @@
<?php
error_reporting(E_ALL | E_STRICT);
include("config.php");
include("database.php");
function LoginPage_Login($dataConnection)
{
$username = trim($_POST["username"]);
$password = trim($_POST["password"]);
if(empty($username))
{
throw new Exception("You must enter an username.");
}
if(empty($password))
{
throw new Exception("You must enter a password.");
}
$userId = VerifyUser($dataConnection, $username, $password);
return RefreshOrCreateSession($dataConnection, $userId);
}
$loginError = "";
$sessionId = "";
if(isset($_POST["login"]))
{
try
{
$sessionId = LoginPage_Login($g_databaseConnection);
setcookie("sessionId", $sessionId);
header("Location: control_panel.php");
}
catch(Exception $e)
{
$loginError = $e->getMessage();
}
}
?>
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Seventh Umbral Server</title>
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/global.css" />
</head>
<body>
<?php include("header.php"); ?>
<div class="info">
<h2>Login</h2>
<br />
<form method="post" autocomplete="off">
<table class="infoForm">
<tr>
<td>Username:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" name="login" value="Login" />
</td>
</tr>
</table>
</form>
<p class="errorMessage"><?php echo($loginError); ?></p>
</div>
<div class="infoFooter">
<a href="create_user.php">Create User</a>
</div>
</body>
</html>

View file

@ -0,0 +1,6 @@
<?php
setcookie("sessionId", "");
header("Location: control_panel_login.php");
?>

View file

@ -0,0 +1,109 @@
<?php
include("config.php");
include("database.php");
//require_once("recaptchalib.php");
function IsUsingSSL()
{
return ($_SERVER['SERVER_PORT'] == 443);
}
function CreateUserPage_CreateUser($databaseConnection)
{
$username = trim($_POST["username"]);
$password = trim($_POST["password"]);
$repeatPassword = trim($_POST["repeatPassword"]);
$email = trim($_POST["email"]);
if(empty($username))
{
throw new Exception("You must enter an username.");
}
if(empty($password))
{
throw new Exception("You must enter a password.");
}
if($password !== $repeatPassword)
{
throw new Exception("Repeated password doesn't match with entered password.");
}
if(empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL))
{
throw new Exception("You must enter a valid e-mail address.");
}
$salt = GenerateRandomSha224();
$saltedPassword = $password . $salt;
$hashedPassword = hash("sha224", $saltedPassword);
InsertUser($databaseConnection, $username, $hashedPassword, $salt, $email);
}
$createUserError = "";
$enteredUserName = "";
$enteredEmail = "";
if(isset($_POST["createUser"]))
{
$enteredUserName = $_POST["username"];
$enteredEmail = $_POST["email"];
try
{
CreateUserPage_CreateUser($g_databaseConnection);
header("Location: create_user_success.php");
die();
}
catch(Exception $e)
{
$createUserError = $e->getMessage();
}
}
?>
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Seventh Umbral Server</title>
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/global.css" />
</head>
<body>
<?php include("header.php"); ?>
<div class="info">
<h2>Create New User</h2>
<br />
<form method="post" autocomplete="off">
<table class="infoForm">
<tr>
<td>Username:</td>
<td><input type="text" name="username" value="<?php echo $enteredUserName; ?>" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td>Repeat Password:</td>
<td><input type="password" name="repeatPassword" /></td>
</tr>
<tr>
<td>E-mail Address:</td>
<td><input type="text" name="email" value="<?php echo $enteredEmail; ?>" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" name="createUser" value="Create User" />
</td>
</tr>
</table>
</form>
<p class="errorMessage"><?php echo($createUserError); ?></p>
</div>
</body>
</html>

View file

@ -0,0 +1,25 @@
<?php
include("config.php");
?>
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Seventh Umbral Server</title>
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/global.css" />
</head>
<body>
<?php include("header.php"); ?>
<div class="info">
<p>
User created successfully.
</p>
<p>
You may now use the Seventh Umbral Launcher to login and connect to this server.
</p>
<p>
<a href="control_panel_login.php">Login to the User Control Panel</a>
</p>
</div>
</body>
</html>

View file

@ -0,0 +1,158 @@
body
{
font-family: Verdana;
font-size: 10pt;
line-height: 14pt;
height: 100%;
}
div.contentContainer {
width: 50%;
float: left;
}
div.info
{
width: 320px;
height: 100%;
margin-left: auto;
margin-right: auto;
text-align: center;
padding: 20px;
background-color: lightgrey;
}
div.infoFooter
{
width: 400px;
margin-left: auto;
margin-right: auto;
text-align: right;
padding: 5px;
}
div.edit
{
width: 50%;
min-width: 600px;
margin-top: 20px;
margin-left: auto;
margin-right: auto;
text-align: center;
padding: 20px;
background-color: lightgrey;
}
div.inner
{
position: relative;
max-width: 1250px;
margin: 0px auto;
}
h1
{
line-height: 23px;
font-size: 23px;
padding: 5px 0px;
}
h2
{
line-height: 17px;
font-size: 14px;
font-weight: bold;
padding: 5px;
}
h3
{
line-height: 14px;
font-size: 12px;
font-weight: bold;
padding: 5px;
}
header.top
{
padding: 20px 0px;
background: none repeat scroll 0% 0% lavender;
position: relative;
z-index: 999;
}
table.center
{
margin-left: auto;
margin-right: auto;
}
table.infoForm
{
width: 100%;
}
table.editForm
{
width: 100%;
}
table.editForm input
{
width: 100%;
}
table.editForm select
{
width: 100%;
}
td
{
padding: 3px;
}
th
{
padding: 3px;
text-decoration: underline;
}
p
{
padding: 2px;
}
p.errorMessage
{
color: darkred;
font-weight: bold;
}
p.pageTitle
{
font-weight: bold;
font-size: 28px;
line-height: 20px;
padding: 0px 0px;
}
p.pageTitle a
{
text-decoration: none;
color: black;
}
p.pageSubTitle
{
font-size: 10px;
line-height: 18px;
padding: 0px 0px;
}
#recaptcha_area
{
margin: 0 auto;
}

View file

@ -0,0 +1,48 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

View file

@ -0,0 +1,445 @@
<?php
include("config.php");
mysqli_report(MYSQLI_REPORT_STRICT);
function CreateDatabaseConnection($server, $username, $password, $database)
{
try
{
$dataConnection = new mysqli($server, $username, $password);
}
catch(Exception $e)
{
die("Error while connecting to the database");
}
$dataConnection->select_db($database);
$dataConnection->query("SET NAMES 'utf8'");
return $dataConnection;
}
$g_databaseConnection = CreateDatabaseConnection($db_server, $db_username, $db_password, $db_database);
function GenerateRandomSha224()
{
mt_srand(microtime(true) * 100000 + memory_get_usage(true));
return hash("sha224", uniqid(mt_rand(), true));
}
function VerifyUser($dataConnection, $username, $password)
{
$statement = $dataConnection->prepare("SELECT id, passhash, salt FROM users WHERE name = ?");
if(!$statement)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
try
{
$statement->bind_param('s', $username);
if(!$statement->execute())
{
throw new Exception(__FUNCTION__ . " failed.");
}
$statement->bind_result($id, $storedPasshash, $salt);
if(!$statement->fetch())
{
throw new Exception("Incorrect username.");
}
$saltedPassword = $password . $salt;
$hashedPassword = hash("sha224", $saltedPassword);
if($hashedPassword !== $storedPasshash)
{
throw new Exception("Incorrect password.");
}
return $id;
}
finally
{
$statement->close();
}
}
function InsertUser($dataConnection, $username, $passhash, $salt, $email)
{
{
$statement = $dataConnection->prepare("INSERT INTO users (name, passhash, salt, email) VALUES (?, ?, ?, ?)");
if(!$statement)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
try
{
$statement->bind_param('ssss', $username, $passhash, $salt, $email);
if(!$statement->execute())
{
throw new Exception(__FUNCTION__ . " failed.");
}
}
finally
{
$statement->close();
}
}
}
function RefreshOrCreateSession($dataConnection, $userId)
{
try
{
$sessionId = GetSessionFromUserId($dataConnection, $userId);
RefreshSession($dataConnection, $sessionId);
}
catch(Exception $e)
{
$sessionId = CreateSession($dataConnection, $userId);
}
return $sessionId;
}
function CreateSession($dataConnection, $userId)
{
//Delete any session that might be active
{
$statement = $dataConnection->prepare("DELETE FROM sessions WHERE userId = ?");
if(!$statement)
{
throw new Exception("Failed to create session: " . $dataConnection->error);
}
try
{
$statement->bind_param('i', $userId);
if(!$statement->execute())
{
throw new Exception("Failed to create session: " . $dataConnection->error);
}
}
finally
{
$statement->close();
}
}
//Create new session
{
$sessionId = GenerateRandomSha224();
$statement = $dataConnection->prepare("INSERT INTO sessions (id, userid, expiration) VALUES (?, ?, NOW() + INTERVAL " . FFXIV_SESSION_LENGTH . " HOUR)");
if(!$statement)
{
throw new Exception("Failed to create session: " . $dataConnection->error);
}
try
{
$statement->bind_param('si', $sessionId, $userId);
if(!$statement->execute())
{
throw new Exception("Failed to create session: " . $dataConnection->error);
}
}
finally
{
$statement->close();
}
return $sessionId;
}
}
function GetSessionFromUserId($dataConnection, $userId)
{
$statement = $dataConnection->prepare("SELECT id FROM sessions WHERE userId = ? AND expiration > NOW()");
if(!$statement)
{
throw new Exception("Failed to get session id: " . $dataConnection->error);
}
try
{
$statement->bind_param('i', $userId);
if(!$statement->execute())
{
throw new Exception("Failed to get session id: " . $dataConnection->error);
}
$statement->bind_result($sessionId);
if(!$statement->fetch())
{
throw new Exception("Failed to get session id: " . $dataConnection->error);
}
return $sessionId;
}
finally
{
$statement->close();
}
}
function RefreshSession($dataConnection, $sessionId)
{
$statement = $dataConnection->prepare("UPDATE sessions SET expiration = NOW() + INTERVAL " . FFXIV_SESSION_LENGTH . " HOUR WHERE id = ?");
if(!$statement)
{
throw new Exception("Failed to refresh session: " . $dataConnection->error);
}
try
{
$statement->bind_param('s', $sessionId);
if(!$statement->execute())
{
throw new Exception("Failed to refresh session: " . $dataConnection->error);
}
}
finally
{
$statement->close();
}
}
function GetUserIdFromSession($dataConnection, $sessionId)
{
$statement = $dataConnection->prepare("SELECT userId FROM sessions WHERE id = ? AND expiration > NOW()");
if(!$statement)
{
throw new Exception("Could not get user id.");
}
try
{
$statement->bind_param('s', $sessionId);
if(!$statement->execute())
{
throw new Exception("Could not get user id.");
}
$statement->bind_result($userId);
if(!$statement->fetch())
{
throw new Exception("Could not get user id.");
}
return $userId;
}
finally
{
$statement->close();
}
}
function GetUserInfo($dataConnection, $userId)
{
$statement = $dataConnection->prepare("SELECT name FROM users WHERE id = ?");
if(!$statement)
{
throw new Exception("Failed to get user information: " . $dataConnection->error);
}
try
{
$statement->bind_param('i', $userId);
if(!$statement->execute())
{
throw new Exception("Failed to get user information: " . $dataConnection->error);
}
$result = $statement->get_result();
if(!$result)
{
throw new Exception("Failed to get user information: " . $dataConnection->error);
}
$row = $result->fetch_assoc();
if(!$row)
{
throw new Exception("Failed to get user information: " . $dataConnection->error);
}
return $row;
}
finally
{
$statement->close();
}
}
function GetUserCharacters($dataConnection, $userId)
{
$statement = $dataConnection->prepare("SELECT id, name FROM characters WHERE userId = ?");
if(!$statement)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
try
{
$statement->bind_param('i', $userId);
if(!$statement->execute())
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$result = $statement->get_result();
if(!$result)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$characters = array();
while(1)
{
$row = $result->fetch_assoc();
if(!$row)
{
break;
}
array_push($characters, $row);
}
return $characters;
}
finally
{
$statement->close();
}
}
function GetCharacterInfo($dataConnection, $userId, $characterId)
{
$query = sprintf("SELECT * FROM characters WHERE userId = '%d' AND id = '%d'",
$userId, $characterId);
$result = $dataConnection->query($query);
if(!$result)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$row = $result->fetch_assoc();
if(!$row)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
return $row;
}
function GetCharacterAppearance($dataConnection, $userId, $characterId)
{
$query = sprintf("SELECT * FROM characters_appearance INNER JOIN characters ON characters_appearance.characterId = characters.id WHERE characters.userId = '%d' AND characters.Id='%d'",
$userId, $characterId);
$result = $dataConnection->query($query);
if(!$result)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$row = $result->fetch_assoc();
if(!$row)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
return $row;
}
function GetCharacterChocobo($dataConnection, $userId, $characterId)
{
$query = sprintf("SELECT * FROM characters_chocobo INNER JOIN characters ON characters_chocobo.characterId = characters.id WHERE characters.userId = '%d' AND characters.Id='%d'",
$userId, $characterId);
$result = $dataConnection->query($query);
if(!$result)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$row = $result->fetch_assoc();
if(!$row)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
return $row;
}
function GetCharacterClassLevels($dataConnection, $userId, $characterId)
{
$query = sprintf("SELECT * FROM characters_class_levels INNER JOIN characters ON characters_class_levels.characterId = characters.id WHERE characters.userId = '%d' AND characters.Id='%d'",
$userId, $characterId);
$result = $dataConnection->query($query);
if(!$result)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
$row = $result->fetch_assoc();
if(!$row)
{
throw new Exception(__FUNCTION__ . " failed: " . $dataConnection->error);
}
return $row;
}
function UpdateCharacterInfo($dataConnection, $characterId, $characterInfo)
{
$statement = $dataConnection->prepare("UPDATE ffxiv_characters SET
name = ?, tribe = ?, size = ?, voice = ?, skinColor = ?, hairStyle = ?, hairColor = ?, hairOption = ?,
eyeColor = ?, faceType = ?, faceBrow = ?, faceEye = ?, faceIris = ?, faceNose = ?, faceMouth = ?, faceJaw = ?,
faceCheek = ?, faceOption1 = ?, faceOption2 = ?, guardian = ?, birthMonth = ?, birthDay = ?, allegiance = ?,
weapon1 = ?, weapon2 = ?, headGear = ?, bodyGear = ?, legsGear = ?, handsGear = ?, feetGear = ?,
waistGear = ?, rightEarGear = ?, leftEarGear = ?, rightFingerGear = ?, leftFingerGear = ?
WHERE id = ?");
if(!$statement)
{
throw new Exception("Failed to update character information: " . $dataConnection->error);
}
try
{
if(!$statement->bind_param("siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
$characterInfo["name"], $characterInfo["tribe"], $characterInfo["size"], $characterInfo["voice"],
$characterInfo["skinColor"], $characterInfo["hairStyle"], $characterInfo["hairColor"],
$characterInfo["hairOption"], $characterInfo["eyeColor"], $characterInfo["faceType"],
$characterInfo["faceBrow"], $characterInfo["faceEye"], $characterInfo["faceIris"],
$characterInfo["faceNose"], $characterInfo["faceMouth"], $characterInfo["faceJaw"],
$characterInfo["faceCheek"], $characterInfo["faceOption1"], $characterInfo["faceOption2"],
$characterInfo["guardian"], $characterInfo["birthMonth"], $characterInfo["birthDay"], $characterInfo["allegiance"],
$characterInfo["weapon1"], $characterInfo["weapon2"], $characterInfo["headGear"], $characterInfo["bodyGear"],
$characterInfo["legsGear"], $characterInfo["handsGear"], $characterInfo["feetGear"],
$characterInfo["waistGear"], $characterInfo["rightEarGear"], $characterInfo["leftEarGear"],
$characterInfo["rightFingerGear"], $characterInfo["leftFingerGear"],
$characterId))
{
throw new Exception("Failed to update character information: " . $dataConnection->error);
}
if(!$statement->execute())
{
throw new Exception("Failed to update character information: " . $dataConnection->error);
}
}
finally
{
$statement->close();
}
}
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

View file

@ -0,0 +1,3 @@
<header class="top">
</header>

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

View file

@ -0,0 +1,89 @@
<?php
error_reporting(E_ALL | E_STRICT);
include("config.php");
include("database.php");
function LoginPage_Login($dataConnection)
{
$username = trim($_POST["username"]);
$password = trim($_POST["password"]);
if(empty($username))
{
throw new Exception("You must enter an username.");
}
if(empty($password))
{
throw new Exception("You must enter a password.");
}
$userId = VerifyUser($dataConnection, $username, $password);
return RefreshOrCreateSession($dataConnection, $userId);
}
$loginError = "";
$sessionId = "";
if(isset($_POST["login"]))
{
try
{
$sessionId = LoginPage_Login($g_databaseConnection);
}
catch(Exception $e)
{
$loginError = $e->getMessage();
}
}
?>
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>FFXIV 1.0 Login</title>
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/global.css" />
</head>
<body>
<?php
if(!empty($sessionId))
{
echo "<script>window.location=\"ffxiv://login_success?sessionId=" . $sessionId . "\";</script>";
}
?>
<div style="width: 80%; height: 300px; margin-left: auto; margin-right: auto; margin-top: 20%">
<div class="contentContainer" >
<img style="width: 100%;" src="./img/logo.png" />
</div>
<div class="contentContainer">
<div class="info">
<br />
<form method="post" autocomplete="off">
<table class="infoForm">
<tr>
<td>Username:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" name="login" value="Login" />
</td>
</tr>
</table>
</form>
<p class="errorMessage"><?php echo($loginError); ?></p>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,146 @@
{
0: {
"name": "Bard Artifact Equipment",
"headGear": 41984,
"bodyGear": 41984,
"legsGear": 41984,
"handsGear": 41984,
"feetGear": 41984,
"waistGear": 0
},
1: {
"name": "Black Mage Artifact Equipment",
"headGear": 40960,
"bodyGear": 40960,
"legsGear": 40960,
"handsGear": 40960,
"feetGear": 40960,
"waistGear": 0
},
2: {
"name": "Dragoon Artifact Equipment",
"headGear": 36864,
"bodyGear": 36864,
"legsGear": 36864,
"handsGear": 36864,
"feetGear": 36864,
"waistGear": 0
},
3: {
"name": "Monk Artifact Equipment",
"headGear": 45056,
"bodyGear": 45056,
"legsGear": 45056,
"handsGear": 45056,
"feetGear": 45056,
"waistGear": 0
},
4: {
"name": "Paladin Artifact Equipment",
"headGear": 43008,
"bodyGear": 43008,
"legsGear": 43008,
"handsGear": 43008,
"feetGear": 43008,
"waistGear": 0
},
5: {
"name": "Warrior Artifact Equipment",
"headGear": 37888,
"bodyGear": 37888,
"legsGear": 37888,
"handsGear": 37888,
"feetGear": 37888,
"waistGear": 0
},
6: {
"name": "White Mage Artifact Equipment",
"headGear": 39936,
"bodyGear": 39936,
"legsGear": 39936,
"handsGear": 39936,
"feetGear": 39936,
"waistGear": 0
},
7: {
"name": "The Maelstrom Uniform",
"headGear": 46080,
"bodyGear": 46080,
"legsGear": 1024,
"handsGear": 46080,
"feetGear": 46080,
"waistGear": 0
},
8: {
"name": "The Order of the Twin Adder Uniform",
"headGear": 46112,
"bodyGear": 46081,
"legsGear": 1024,
"handsGear": 46081,
"feetGear": 46081,
"waistGear": 0
},
9: {
"name": "The Immortal Flames Uniform",
"headGear": 46144,
"bodyGear": 46082,
"legsGear": 1024,
"handsGear": 46082,
"feetGear": 46082,
"waistGear": 0
},
10: {
"name": "Alberic",
"headGear": 0,
"bodyGear": 15744,
"legsGear": 7238,
"handsGear": 11584,
"feetGear": 15744,
"waistGear": 0
},
11: {
"name": "Jehantel",
"headGear": 9604,
"bodyGear": 28742,
"legsGear": 28928,
"handsGear": 1024,
"feetGear": 9412,
"waistGear": 0
},
12: {
"name": "Miraudont",
"headGear": 19503,
"bodyGear": 14598,
"legsGear": 3268,
"handsGear": 14560,
"feetGear": 13475,
"waistGear": 248832
},
13: {
"name": "Nael van Darnus (Elezen Male Only)",
"headGear": 0,
"bodyGear": 933888,
"legsGear": 1024,
"handsGear": 1024,
"feetGear": 1024,
"waistGear": 0
},
14: {
"name": "Papalymo",
"headGear": 20507,
"bodyGear": 7589,
"legsGear": 16641,
"handsGear": 3265,
"feetGear": 9504,
"waistGear": 168960
},
15: {
"name": "Rubh Epocan",
"headGear": 20576,
"bodyGear": 7232,
"legsGear": 5198,
"handsGear": 6209,
"feetGear": 6209,
"waistGear": 248832
},
};

View file

@ -0,0 +1,107 @@
{
0: {
"name": "Axe",
"weapon1": 147850240,
"weapon2": 0,
},
1: {
"name": "Bow & Arrow",
"weapon1": 210766878,
"weapon2": 236979210,
},
2: {
"name": "Fists",
"weapon1": 58723358,
"weapon2": 59771934,
},
3: {
"name": "Lance",
"weapon1": 168826880,
"weapon2": 0,
},
4: {
"name": "Sword & Shield",
"weapon1": 79692880,
"weapon2": 32513024,
},
5: {
"name": "Wand (Conjurer)",
"weapon1": 331351052,
"weapon2": 0,
},
6: {
"name": "Wand (Thaumaturge)",
"weapon1": 294652958,
"weapon2": 0,
},
7: {
"name": "Ifrit's Battleaxe",
"weapon1": 147857408,
"weapon2": 0,
},
8: {
"name": "Ifrit's Bow",
"weapon1": 210768896,
"weapon2": 0,
},
9: {
"name": "Ifrit's Claws",
"weapon1": 62915584,
"weapon2": 63964160,
},
10: {
"name": "Ifrit's Harpoon",
"weapon1": 175113216,
"weapon2": 0,
},
11: {
"name": "Ifrit's Blade",
"weapon1": 81789952,
"weapon2": 0,
},
12: {
"name": "Ifrit's Cane",
"weapon1": 347086848,
"weapon2": 0,
},
13: {
"name": "Ifrit's Cudgel",
"weapon1": 294653952,
"weapon2": 0,
},
14: {
"name": "Bravura",
"weapon1": 147856384,
"weapon2": 0,
},
15: {
"name": "Artemis Bow",
"weapon1": 212861952,
"weapon2": 0,
},
16: {
"name": "Sphairai",
"weapon1": 65012736,
"weapon2": 66061312,
},
17: {
"name": "Gae Bolg",
"weapon1": 173016064,
"weapon2": 0,
},
18: {
"name": "Curtana & Holy Shield",
"weapon1": 79702016,
"weapon2": 32517120,
},
19: {
"name": "Thyrus",
"weapon1": 347084800,
"weapon2": 0,
},
20: {
"name": "Stardust Rod",
"weapon1": 310380544,
"weapon2": 0,
},
};

View file

@ -0,0 +1,3 @@
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

123
Data/www/vercheck/index.php Normal file
View file

@ -0,0 +1,123 @@
<?php
require 'patches.php';
function getCurrentUri()
{
$basepath = implode('/', array_slice(explode('/', $_SERVER['SCRIPT_NAME']), 0, -1)) . '/';
$uri = substr($_SERVER['REQUEST_URI'], strlen($basepath));
if (strstr($uri, '?')) $uri = substr($uri, 0, strpos($uri, '?'));
$uri = '/' . trim($uri, '/');
return $uri;
}
function checkBootVersion($version)
{
global $LATEST_BOOT_VERSION, $BOOT_PATCHES;
if ($version != $LATEST_BOOT_VERSION)
{
if (!isset($BOOT_PATCHES[$version]))
{
header("HTTP/1.0 404 NOT FOUND");
return;
}
header("HTTP/1.0 200 OK");
header("Content-Location: ffxiv/2d2a390f/vercheck.dat");
header("Content-Type: multipart/mixed; boundary=477D80B1_38BC_41d4_8B48_5273ADB89CAC");
header("X-Repository: ffxiv/win32/release/boot");
header("X-Patch-Module: ZiPatch");
header("X-Protocol: torrent");
header("X-Info-Url: http://example.com");
header("X-Latest-Version: $LATEST_BOOT_VERSION");
header("Connection: keep-alive");
echo "--477D80B1_38BC_41d4_8B48_5273ADB89CAC\r\n";
echo "Content-Type: application/octet-stream\r\n";
echo "Content-Location: ffxiv/2d2a390f/metainfo/D$BOOT_PATCHES[$version].torrent\r\n";
echo "X-Patch-Length: " . filesize("./ffxiv/2d2a390f/patch/D$BOOT_PATCHES[$version].patch") . "\r\n";
echo "X-Signature: jqxmt9WQH1aXptNju6CmCdztFdaKbyOAVjdGw_DJvRiBJhnQL6UlDUcqxg2DeiIKhVzkjUm3hFXOVUFjygxCoPUmCwnbCaryNqVk_oTk_aZE4HGWNOEcAdBwf0Gb2SzwAtk69zs_5dLAtZ0mPpMuxWJiaNSvWjEmQ925BFwd7Vk=\r\n";
echo "test: $version";
echo "\r\n";
readfile("./ffxiv/2d2a390f/metainfo/D$BOOT_PATCHES[$version].torrent");
echo "\r\n";
echo "--477D80B1_38BC_41d4_8B48_5273ADB89CAC--\r\n\r\n";
}
else
{
header("HTTP/1.0 204 No Content");
header("Content-Location: ffxiv/48eca647/vercheck.dat");
header("X-Repository: ffxiv/win32/release/boot");
header("X-Patch-Module: ZiPatch");
header("X-Protocol: torrent");
header("X-Info-Url: http://www.example.com");
header("X-Latest-Version: $LATEST_BOOT_VERSION");
}
}
function checkGameVersion($version)
{
global $LATEST_GAME_VERSION, $GAME_PATCHES;
if ($version != $LATEST_GAME_VERSION)
{
if (!isset($GAME_PATCHES[$version]))
{
header("HTTP/1.0 404 NOT FOUND");
return;
}
header("HTTP/1.0 200 OK");
header("Content-Location: ffxiv/48eca647/vercheck.dat");
header("Content-Type: multipart/mixed; boundary=477D80B1_38BC_41d4_8B48_5273ADB89CAC");
header("X-Repository: ffxiv/win32/release/game");
header("X-Patch-Module: ZiPatch");
header("X-Protocol: torrent");
header("X-Info-Url: http://example.com");
header("X-Latest-Version: $LATEST_GAME_VERSION");
header("Connection: keep-alive");
echo "--477D80B1_38BC_41d4_8B48_5273ADB89CAC\r\n";
echo "Content-Type: application/octet-stream\r\n";
echo "Content-Location: ffxiv/48eca647/metainfo/D$GAME_PATCHES[$version].torrent\r\n";
echo "X-Patch-Length: " . filesize("./ffxiv/48eca647/patch/D$GAME_PATCHES[$version].patch") . "\r\n";
echo "X-Signature: jqxmt9WQH1aXptNju6CmCdztFdaKbyOAVjdGw_DJvRiBJhnQL6UlDUcqxg2DeiIKhVzkjUm3hFXOVUFjygxCoPUmCwnbCaryNqVk_oTk_aZE4HGWNOEcAdBwf0Gb2SzwAtk69zs_5dLAtZ0mPpMuxWJiaNSvWjEmQ925BFwd7Vk=\r\n";
echo "\r\n";
readfile("./ffxiv/48eca647/metainfo/D$GAME_PATCHES[$version].torrent");
echo "\r\n";
echo "--477D80B1_38BC_41d4_8B48_5273ADB89CAC--\r\n\r\n";
}
else
{
header("HTTP/1.0 204 No Content");
header("Content-Location: ffxiv/48eca647/vercheck.dat");
header("X-Repository: ffxiv/win32/release/game");
header("X-Patch-Module: ZiPatch");
header("X-Protocol: torrent");
header("X-Info-Url: http://www.example.com");
header("X-Latest-Version: $LATEST_GAME_VERSION");
}
}
//Find the version request
$base_url = getCurrentUri();
$routes = array();
$routes = explode('/', $base_url);
//Are we even updating FFXIV?
if ($routes[1] == "ffxiv" &&
$routes[2] == "win32" &&
$routes[3] == "release"){
//Updating Launcher
if ($routes[4] == "boot")
checkBootVersion($routes[5]);
//Updating Game
else if ($routes[4] == "game")
checkGameVersion($routes[5]);
}
?>

View file

@ -0,0 +1,64 @@
<?php
$LATEST_BOOT_VERSION = "2010.09.18.0000";
$LATEST_GAME_VERSION = "2012.09.19.0001";
$BOOT_PATCHES = array(
"2010.07.10.0000" => "2010.09.18.0000",
);
$GAME_PATCHES = array(
"2010.07.10.0000" => "2010.09.19.0000",
"2010.09.19.0000" => "2010.09.23.0000",
"2010.09.23.0000" => "2010.09.28.0000",
"2010.09.28.0000" => "2010.10.07.0001",
"2010.10.07.0001" => "2010.10.14.0000",
"2010.10.14.0000" => "2010.10.22.0000",
"2010.10.22.0000" => "2010.10.26.0000",
"2010.10.26.0000" => "2010.11.25.0002",
"2010.11.25.0002" => "2010.11.30.0000",
"2010.11.30.0000" => "2010.12.06.0000",
"2010.12.06.0000" => "2010.12.13.0000",
"2010.12.13.0000" => "2010.12.21.0000",
"2010.12.21.0000" => "2011.01.18.0000",
"2011.01.18.0000" => "2011.02.01.0000",
"2011.02.01.0000" => "2011.02.10.0000",
"2011.02.10.0000" => "2011.03.01.0000",
"2011.03.01.0000" => "2011.03.24.0000",
"2011.03.24.0000" => "2011.03.30.0000",
"2011.03.30.0000" => "2011.04.13.0000",
"2011.04.13.0000" => "2011.04.21.0000",
"2011.04.21.0000" => "2011.05.19.0000",
"2011.05.19.0000" => "2011.06.10.0000",
"2011.06.10.0000" => "2011.07.20.0000",
"2011.07.20.0000" => "2011.07.26.0000",
"2011.07.26.0000" => "2011.08.05.0000",
"2011.08.05.0000" => "2011.08.09.0000",
"2011.08.09.0000" => "2011.08.16.0000",
"2011.08.16.0000" => "2011.10.04.0000",
"2011.10.04.0000" => "2011.10.12.0001",
"2011.10.12.0001" => "2011.10.27.0000",
"2011.10.27.0000" => "2011.12.14.0000",
"2011.12.14.0000" => "2011.12.23.0000",
"2011.12.23.0000" => "2012.01.18.0000",
"2012.01.18.0000" => "2012.01.24.0000",
"2012.01.24.0000" => "2012.01.31.0000",
"2012.01.31.0000" => "2012.03.07.0000",
"2012.03.07.0000" => "2012.03.09.0000",
"2012.03.09.0000" => "2012.03.22.0000",
"2012.03.22.0000" => "2012.03.29.0000",
"2012.03.29.0000" => "2012.04.04.0000",
"2012.04.04.0000" => "2012.04.23.0001",
"2012.04.23.0001" => "2012.05.08.0000",
"2012.05.08.0000" => "2012.05.15.0000",
"2012.05.15.0000" => "2012.05.22.0000",
"2012.05.22.0000" => "2012.06.06.0000",
"2012.06.06.0000" => "2012.06.19.0000",
"2012.06.19.0000" => "2012.06.26.0000",
"2012.06.26.0000" => "2012.07.21.0000",
"2012.07.21.0000" => "2012.08.10.0000",
"2012.08.10.0000" => "2012.09.06.0000",
"2012.09.06.0000" => "2012.09.19.0001",
);
?>