1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-23 18:17:46 +00:00

Merge branch 'master' into master

This commit is contained in:
amibu01 2017-09-06 19:24:24 +02:00 committed by GitHub
commit ca8c40a1b2
28 changed files with 419 additions and 141 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

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

View file

@ -0,0 +1,65 @@
div#TopDiv{
padding:10px;
}
img{
display:block;
margin-left:auto;
margin-right:auto;
}
h2.text-center{
color:#fff;
}
h1.text-center{
color:#FFF;
}
div.login-card{
background-color:#282828;
}
p{
color:#fff;
}
input.input-sm{
display:block;
margin-left:auto;
margin-right:auto;
}
div#Conttwo.container{
display:block;
width:300px;
background-color:rgba(17, 17, 17, 0.77);
}
div#Split{
padding:2px;
}
p{
display:block;
margin-left:auto;
margin-right:auto;
}
input{
display:block;
margin-left:auto;
margin-right:auto;
}
button.btn.btn-default{
display:block;
margin-left:auto;
margin-right:auto;
color:#000;
}
div#space{
padding:3px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

5
bin/web/assets/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,10 +1,14 @@
<!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" />
<script src="//cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sapphire Create Account</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="assets/css/global.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script>
function doLogin(){
var url = "sapphire-api/lobby/createAccount";
@ -19,7 +23,7 @@
var parsed = JSON.parse(response);
window.external.Boot(parsed.sId, parsed.lobbyHost, parsed.frontierHost);
}catch(err){
document.getElementById("errorMessage").innerHTML = "Login failed.";
document.getElementById("Error").innerHTML = "Create User failed.";
}
}
}
@ -39,35 +43,28 @@
return data;
}
</script>
</head>
<body oncontextmenu="return false;">
<div style="width: 80%; height: 300px; margin-left: auto; margin-right: auto; margin-top: 20%">
<div class="contentContainer" >
<img style="width: 100%;" src="./sapphire_logo.png" />
</div>
<div class="contentContainer">
<div class="info">
<br />
<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 id="submitButton" type="button" value="Create User" onclick="doLogin();" />
</td>
</tr>
</table>
<p class="errorMessage" id="errorMessage"></p>
</div>
</div>
</div>
</body>
</html>
</head>
<body>
<div id="TopDiv"></div>
<div class="container"><img src="assets/img/sapphire_logo.png" width="40%" height="40%"></div>
<div class="container" id="Conttwo">
<div></div>
<h1 class="text-center">Create Account</h1>
<p class="text-center">Username: </p>
<td><input type="text" name="username" /></td>
<div id="Split"></div>
<p class="text-center">Password: </p>
<td><input type="password" name="password" /></td>
<div id="space"></div>
<button class="btn btn-default" input id="submitButton" onclick="doLogin()">Create User</button>
<p id="Error" class="text-center"></p>
<div id="Split">
<p id="CreateUser"><a href="login.html"><span style="text-decoration: underline;">Back to Login</span></a></p>
</div>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>

View file

@ -1,10 +1,14 @@
<!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" />
<script src="//cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sapphire login</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="assets/css/global.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script>
function doLogin(){
var url = "sapphire-api/lobby/login";
@ -19,7 +23,7 @@
var parsed = JSON.parse(response);
window.external.Boot(parsed.sId, parsed.lobbyHost, parsed.frontierHost);
}catch(err){
document.getElementById("errorMessage").innerHTML = "Login failed.";
document.getElementById("Error").innerHTML = "Login failed.";
}
}
}
@ -39,37 +43,28 @@
return data;
}
</script>
</head>
<body oncontextmenu="return false;">
<div style="width: 80%; height: 300px; margin-left: auto; margin-right: auto; margin-top: 20%">
<div class="contentContainer" >
<img style="width: 100%;" src="./sapphire_logo.png" />
</div>
<div class="contentContainer">
<div class="info">
<br />
<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 id="submitButton" type="button" value="Login" onclick="doLogin();" />
</td>
</tr>
</table>
<p class="errorMessage" id="errorMessage"></p>
<br>
<a href="createUser.html">Create Account</a>
</div>
</div>
</div>
</body>
</html>
</head>
<body>
<div id="TopDiv"></div>
<div class="container"><img src="assets/img/sapphire_logo.png" width="40%" height="40%"></div>
<div class="container" id="Conttwo">
<div></div>
<h1 class="text-center">Login To Account</h1>
<p class="text-center">Username: </p>
<td><input type="text" name="username" /></td>
<div id="Split"></div>
<p class="text-center">Password: </p>
<td><input type="password" name="password" /></td>
<div id="space"></div>
<button class="btn btn-default" input id="submitButton" onclick="doLogin()">Login</button>
<p id="Error" class="text-center"></p>
<div id="Split">
<p id="CreateUser"><a href="createUser.html"><span style="text-decoration: underline;">Create Account</span></a></p>
</div>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>

View file

@ -545,13 +545,37 @@ namespace Core {
FcTalk = 0x001F,
};
enum ActionType : uint8_t
enum struct ActionAspect : uint8_t
{
None = 0, // Doesn't imply unaspected
Fire = 1,
Ice = 2,
Wind = 3,
Stone = 4,
Lightning = 5,
Water = 6,
Unaspected = 7 // Doesn't imply magical unaspected damage - could be unaspected physical
};
enum struct ActionType : int8_t
{
WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)?
Unknown_0 = 0,
Slashing = 1,
Piercing = 2,
Blunt = 3,
Unknown_4 = 4,
Magical = 5,
Darkness = 6,
Unknown_7 = 7,
LimitBreak = 8,
};
enum HandleActionType : uint8_t
{
Event,
Spell,
Teleport
};
enum HandleSkillType : uint8_t

View file

@ -324,28 +324,33 @@ bool Core::Data::ExdData::loadActionInfo()
continue;
}
std::string name = getField< std::string >( fields, 0 );
uint8_t category = getField< uint8_t >( fields, 3 );
std::string name = getField< std::string >( fields, 0 ); // 0
uint8_t category = getField< uint8_t >( fields, 3 ); // 3
int8_t class_job = getField< int8_t >( fields, 10 );//9
uint8_t unlock_level = getField< uint8_t >( fields, 11 );//10
int8_t range = getField< int8_t >( fields, 13 );//11
bool can_target_self = getField< bool >( fields, 14 );//12
bool can_target_party = getField< bool>( fields, 15 );//13
bool can_target_friendly = getField< bool >( fields, 16 );//14
bool can_target_enemy = getField< bool >( fields, 17 );//15
int8_t class_job = getField< int8_t >( fields, 10 ); // 10
uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11
int8_t range = getField< int8_t >( fields, 13 ); // 13
bool can_target_self = getField< bool >( fields, 14 ); // 14
bool can_target_party = getField< bool>( fields, 15 ); // 15
bool can_target_friendly = getField< bool >( fields, 16 ); // 16
bool can_target_enemy = getField< bool >( fields, 17 ); // 17
bool is_aoe = getField< bool >( fields, 20 );//18
bool is_aoe = getField< bool >( fields, 20 ); // 20
// Column 23: Seems to be related to raising skills (Raise, Resurrection, Reanimate)
bool can_target_ko = getField< bool >( fields, 24 ); // 24
bool can_target_ko = getField< bool >( fields, 24 );//22
uint8_t aoe_type = getField< uint8_t >( fields, 26 ); // 26
uint8_t radius = getField< uint8_t >( fields, 27 ); // 27
uint8_t aoe_type = getField< uint8_t >( fields, 26 );//24
uint8_t radius = getField< uint8_t >( fields, 27 );//25
uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30
uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31
uint8_t points_type = getField< uint8_t >( fields, 30 );//28
uint16_t points_cost = getField< uint16_t >( fields, 31 );//29
uint32_t instantval = getField< bool >( fields, 35 ); // 35
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37
uint32_t instantval = getField< bool >( fields, 35 );
int8_t model = getField< int8_t >( fields, 39 ); // 39: Action model
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40: Action aspect
uint8_t typeshift = 0x6;
uint8_t mask = 1 << typeshift;
@ -353,8 +358,7 @@ bool Core::Data::ExdData::loadActionInfo()
bool final = ( instantval & mask ) == mask;
bool is_instant = final;
uint16_t cast_time = getField< uint16_t >( fields, 36 );
uint16_t recast_time = getField< uint16_t >( fields, 37 );
info.id = id;
info.name = name;
@ -382,6 +386,9 @@ bool Core::Data::ExdData::loadActionInfo()
info.cast_time = cast_time * 100;
info.recast_time = recast_time * 100;
info.model = model;
info.aspect = aspect;
m_actionInfoMap[id] = info;
}

View file

@ -222,30 +222,33 @@ namespace Core {
struct ActionInfo
{
uint32_t id;
std::string name; //0
uint16_t category;//3
std::string name; // 0
uint16_t category; // 3
int8_t class_job;//9
uint8_t unlock_level;//10
int8_t range;//11
bool can_target_self;//12
bool can_target_party;//13
bool can_target_friendly;//14
bool can_target_enemy;//15
int8_t class_job; // 10
uint8_t unlock_level; // 11
int8_t range; // 13
bool can_target_self; // 14
bool can_target_party; // 15
bool can_target_friendly; // 16
bool can_target_enemy; // 17
bool is_aoe;//18
bool is_aoe; // 20
bool can_target_ko;//22
bool can_target_ko; // 24
uint8_t aoe_type;//24
uint8_t radius;//25
uint8_t aoe_type; // 26
uint8_t radius; // 27
uint8_t points_type;//28
uint16_t points_cost;//29
uint8_t points_type; // 30
uint16_t points_cost; // 31
bool is_instant;//33
uint32_t cast_time;//34
uint32_t recast_time;//35
bool is_instant; // 35
uint32_t cast_time; // 36
uint32_t recast_time; // 37
int8_t model; // 39
uint8_t aspect; // 40
};
struct EventItemInfo

View file

@ -17,9 +17,9 @@ uint32_t Core::Action::Action::getId() const
return m_id;
}
Core::Common::ActionType Core::Action::Action::getActionType() const
Core::Common::HandleActionType Core::Action::Action::getHandleActionType() const
{
return m_actionType;
return m_handleActionType;
}
Core::Entity::ActorPtr Core::Action::Action::getTargetActor() const

View file

@ -15,7 +15,7 @@ namespace Core { namespace Action {
uint32_t getId() const;
Common::ActionType getActionType() const;
Common::HandleActionType getHandleActionType() const;
Entity::ActorPtr getTargetActor() const;
@ -42,7 +42,7 @@ namespace Core { namespace Action {
protected:
uint32_t m_id;
Common::ActionType m_actionType;
Common::HandleActionType m_handleActionType;
uint64_t m_startTime;
uint32_t m_castTime;

View file

@ -22,14 +22,14 @@ extern Core::Scripting::ScriptManager g_scriptMgr;
Core::Action::ActionCast::ActionCast()
{
m_actionType = Common::ActionType::Event;
m_handleActionType = Common::HandleActionType::Event;
}
Core::Action::ActionCast::ActionCast( Entity::ActorPtr pActor, Entity::ActorPtr pTarget, uint32_t actionId )
{
m_startTime = 0;
m_id = actionId;
m_actionType = ActionType::Spell;
m_handleActionType = HandleActionType::Spell;
m_castTime = g_exdData.m_actionInfoMap[actionId].cast_time; // TODO: Add security checks.
m_pSource = pActor;
m_pTarget = pTarget;

View file

@ -18,14 +18,14 @@ extern Core::Logger g_log;
Core::Action::ActionTeleport::ActionTeleport()
{
m_actionType = Common::ActionType::Event;
m_handleActionType = Common::HandleActionType::Event;
}
Core::Action::ActionTeleport::ActionTeleport( Entity::ActorPtr pActor, uint16_t targetZone, uint16_t cost )
{
m_startTime = 0;
m_id = 5;
m_actionType = ActionType::Teleport;
m_handleActionType = HandleActionType::Teleport;
m_castTime = g_exdData.m_actionInfoMap[5].cast_time; // TODO: Add security checks.
m_pSource = pActor;
m_bInterrupt = false;

View file

@ -18,14 +18,14 @@ using namespace Core::Network::Packets::Server;
Core::Action::EventAction::EventAction()
{
m_actionType = Common::ActionType::Event;
m_handleActionType = Common::HandleActionType::Event;
}
Core::Action::EventAction::EventAction( Entity::ActorPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional )
{
m_additional = additional;
m_actionType = ActionType::Event;
m_handleActionType = HandleActionType::Event;
m_eventId = eventId;
m_id = action;
m_castTime = g_exdData.m_EventActionInfoMap[action].castTime; // TODO: Add security checks.

View file

@ -19,14 +19,14 @@ using namespace Core::Network::Packets::Server;
Core::Action::EventItemAction::EventItemAction()
{
m_actionType = Common::ActionType::Event;
m_handleActionType = Common::HandleActionType::Event;
}
Core::Action::EventItemAction::EventItemAction( Entity::ActorPtr pActor, uint32_t eventId, uint32_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional )
{
m_additional = additional;
m_actionType = ActionType::Event;
m_handleActionType = HandleActionType::Event;
m_eventId = eventId;
m_id = action;
// TODO: read the cast time from the action itself

View file

@ -645,8 +645,13 @@ void Core::Entity::Actor::addStatusEffectByIdIfNotExist( int32_t id, int32_t dur
}
}
/*! \param Status that should be removed, based on its ID. */
void Core::Entity::Actor::removeSingleStatusEffectFromId( int32_t id )
{
m_pStatusEffectContainer->removeSingleStatusEffectFromId( id );
}
Core::StatusEffect::StatusEffectContainerPtr Core::Entity::Actor::getStatusEffectContainer() const
{
return m_pStatusEffectContainer;
}

View file

@ -298,6 +298,9 @@ public:
// add a status effect by id if it doesn't exist
void addStatusEffectByIdIfNotExist( int32_t id, int32_t duration, uint16_t param = 0 );
// remove a status effect by id
void removeSingleStatusEffectFromId( int32_t id );
StatusEffect::StatusEffectContainerPtr getStatusEffectContainer() const;
// TODO: Why did i even declare them publicly here?!

View file

@ -1460,9 +1460,9 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget )
uint32_t damage = mainWeap->getAutoAttackDmg();
uint32_t variation = 0 + rand() % 3;
if (getClass() == JOB_MACHINIST ||
if ( getClass() == JOB_MACHINIST ||
getClass() == JOB_BARD ||
getClass() == CLASS_ARCHER)
getClass() == CLASS_ARCHER )
{
GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket(getId());
effectPacket.data().targetId = pTarget->getId();

View file

@ -207,7 +207,7 @@ public:
/*! equip a weapon, possibly forcing a job change */
void equipWeapon( ItemPtr pItem );
/*! get a const pointer to the inventory object */
InventoryPtr getInvetory() const;
InventoryPtr getInventory() const;
/*! get the current main hand model */
uint64_t getModelMainWeapon() const;
/*! get the current off hand model */

View file

@ -16,7 +16,7 @@ using namespace Core::Common;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
Core::InventoryPtr Core::Entity::Player::getInvetory() const
Core::InventoryPtr Core::Entity::Player::getInventory() const
{
return m_pInventory;
}

View file

@ -106,6 +106,12 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
pPlayer->changeTarget( targetId );
break;
}
case 0x68: // Remove status (clicking it off)
{
// todo: check if status can be removed by client from exd
pPlayer->removeSingleStatusEffectFromId( param1 );
break;
}
case 0x69: // Cancel cast
{
if( pPlayer->checkAction() )

View file

@ -63,19 +63,19 @@ void Core::Network::GameConnection::inventoryModifyHandler( const Packets::GameP
case 0x07: // discard item action
{
pPlayer->getInvetory()->discardItem( fromContainer, fromSlot );
pPlayer->getInventory()->discardItem( fromContainer, fromSlot );
}
break;
case 0x08: // move item action
{
pPlayer->getInvetory()->moveItem( fromContainer, fromSlot, toContainer, toSlot );
pPlayer->getInventory()->moveItem( fromContainer, fromSlot, toContainer, toSlot );
}
break;
case 0x09: // swap item action
{
pPlayer->getInvetory()->swapItem( fromContainer, fromSlot, toContainer, toSlot );
pPlayer->getInventory()->swapItem( fromContainer, fromSlot, toContainer, toSlot );
}
break;

View file

@ -47,7 +47,7 @@ namespace Server {
//m_data.tPMax = 3000;
m_data.level = pPlayer->getLevel();
memcpy( m_data.look, pPlayer->getLookArray(), 26 );
auto item = pPlayer->getInvetory()->getItemAt( Inventory::GearSet0, 0 );
auto item = pPlayer->getInventory()->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand );
if( item )
m_data.mainWeaponModel = item->getModelId1();
m_data.secWeaponModel = pPlayer->getModelSubWeapon();

View file

@ -81,6 +81,18 @@ void Core::StatusEffect::StatusEffectContainer::addStatusEffect( StatusEffectPtr
}
void Core::StatusEffect::StatusEffectContainer::removeSingleStatusEffectFromId( uint32_t id )
{
for (auto effectIt : m_effectMap)
{
if (effectIt.second->getId() == id)
{
removeStatusEffect( effectIt.first );
break;
}
}
}
void Core::StatusEffect::StatusEffectContainer::removeStatusEffect( uint8_t effectSlotId )
{
auto pEffectIt = m_effectMap.find( effectSlotId );

View file

@ -21,6 +21,7 @@ public:
void addStatusEffect( StatusEffectPtr pEffect );
void removeStatusEffect( uint8_t effectSlotId );
void removeSingleStatusEffectFromId( uint32_t id );
void update();
bool hasStatusEffect( uint32_t id );