Cleaned up namespaces (still have to do Map Project) and removed references to FFXIV Classic from the code. Removed the Launcher Editor project as it is no longer needed (host file editing is cleaner).
15
data/www/login/config.php
Normal 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
|
||||
|
||||
?>
|
3
data/www/login/css/login.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
.loginBody {
|
||||
background-color: #EFEFEF;
|
||||
}
|
388
data/www/login/database.php
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
BIN
data/www/login/img/banner.png
Normal file
After Width: | Height: | Size: 125 KiB |
BIN
data/www/login/img/btLogin.gif
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
data/www/login/img/lbSQEXId_mem.gif
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
data/www/login/img/lbSQEXPass_mem.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
data/www/login/img/logo.png
Normal file
After Width: | Height: | Size: 118 KiB |
151
data/www/login/index.php
Normal 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"> </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>
|
13
data/www/login_su/config.php
Normal 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
|
||||
|
||||
?>
|
50
data/www/login_su/control_panel.php
Normal 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>
|
20
data/www/login_su/control_panel_common.php
Normal 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;
|
||||
}
|
||||
|
||||
?>
|
754
data/www/login_su/control_panel_edit_character.php
Normal 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>
|
8
data/www/login_su/control_panel_header.php
Normal 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>
|
81
data/www/login_su/control_panel_login.php
Normal 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>
|
6
data/www/login_su/control_panel_logout.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
setcookie("sessionId", "");
|
||||
header("Location: control_panel_login.php");
|
||||
|
||||
?>
|
109
data/www/login_su/create_user.php
Normal 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>
|
25
data/www/login_su/create_user_success.php
Normal 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>
|
158
data/www/login_su/css/global.css
Normal 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;
|
||||
}
|
48
data/www/login_su/css/reset.css
Normal 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;
|
||||
}
|
445
data/www/login_su/database.php
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
BIN
data/www/login_su/favicon.ico
Normal file
After Width: | Height: | Size: 198 KiB |
3
data/www/login_su/header.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<header class="top">
|
||||
|
||||
</header>
|
BIN
data/www/login_su/img/logo.png
Normal file
After Width: | Height: | Size: 114 KiB |
89
data/www/login_su/login.php
Normal 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>
|
146
data/www/login_su/presets_armor.json
Normal 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
|
||||
},
|
||||
};
|
107
data/www/login_su/presets_weapon.json
Normal 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,
|
||||
},
|
||||
};
|
3
data/www/vercheck/.htaccess
Normal file
|
@ -0,0 +1,3 @@
|
|||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [QSA,L]
|
123
data/www/vercheck/index.php
Normal 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]);
|
||||
}
|
||||
?>
|
64
data/www/vercheck/patches.php
Normal 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",
|
||||
);
|
||||
|
||||
?>
|