Updated Map Server namespace. Moved all other data folders (www and sql) to data folder. Renamed boot name to Project Meteor.
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",
|
||||
);
|
||||
|
||||
?>
|