1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-24 13:47:46 +00:00

Merge branch 'master' into develop

# Conflicts:
#	FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj
#	FFXIVClassic Map Server/Database.cs
#	FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
#	FFXIVClassic Map Server/PacketProcessor.cs
#	FFXIVClassic Map Server/WorldManager.cs
#	FFXIVClassic Map Server/actors/Actor.cs
#	FFXIVClassic Map Server/actors/area/Area.cs
#	FFXIVClassic Map Server/actors/chara/player/Player.cs
#	FFXIVClassic Map Server/lua/LuaPlayer.cs
#	data/scripts/base/chara/npc/populace/PopulaceChocoboLender.lua
#	data/scripts/commands/gm/speed.lua
#	data/scripts/commands/gm/warp.lua
#	data/scripts/global.lua
#	data/scripts/player.lua
#	data/scripts/unique/fst0Town01a/PopulaceStandard/khuma_moshroca.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/ahldskyf.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/angry_river.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/ansgor.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/arnegis.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/arthurioux.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/astrid.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/audaine.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/bango_zango.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/bayard.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/bloemerl.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/bmallpa.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/bnhapla.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/chichiroon.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/drowsy-eyed_adventurer.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/eugennoix.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/fickle_beggar.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/hob.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/ivan.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/maetistym.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/mharelak.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/muscle-bound_deckhand.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/pasty-faced_adventurer.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/pearly-toothed_porter.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/ptahjha.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/suspicious-looking_traveler.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/syhrdaeg.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/syngsmyd.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/tatasako.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/tefh_moshroca.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/thata_khamazom.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/thosinbaen.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/tittering_traveler.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/totoruto.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/triaine.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/trinne.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/unconscious_adventurer.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/undsatz.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/vhynho.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/waekbyrt.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/whahtoa.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/wyra_khamazom.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/wyrstmann.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/xavalien.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/zonggo.lua
#	data/scripts/unique/sea0Town01a/PopulaceStandard/zuzule.lua
#	sql/server_zones_spawnlocations.sql
This commit is contained in:
Filip Maj 2017-08-26 13:53:23 -04:00
commit 74ce5a2fe1
56 changed files with 805 additions and 271 deletions

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props')" /> <Import Project="..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props') AND '$(OS)' == 'Windows_NT'" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props') AND '$(OS)' == 'Windows_NT'" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

View file

@ -10,6 +10,7 @@ using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.actors.chara.player; using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.packets.receive.supportdesk;
namespace FFXIVClassic_Map_Server namespace FFXIVClassic_Map_Server
{ {
@ -29,10 +30,10 @@ namespace FFXIVClassic_Map_Server
cmd.Parameters.AddWithValue("@sessionId", sessionId); cmd.Parameters.AddWithValue("@sessionId", sessionId);
using (MySqlDataReader Reader = cmd.ExecuteReader()) using (MySqlDataReader Reader = cmd.ExecuteReader())
{ {
while (Reader.Read()) while (Reader.Read())
{ {
id = Reader.GetUInt32("userId"); id = Reader.GetUInt32("userId");
} }
} }
} }
catch (MySqlException e) catch (MySqlException e)
@ -757,7 +758,7 @@ namespace FFXIVClassic_Map_Server
{ {
if (reader.Read()) if (reader.Read())
{ {
player.charaWork.battleSave.skillLevel[Player.CLASSID_PUG-1] = reader.GetInt16("pug"); player.charaWork.battleSave.skillLevel[Player.CLASSID_PUG - 1] = reader.GetInt16("pug");
player.charaWork.battleSave.skillLevel[Player.CLASSID_GLA - 1] = reader.GetInt16("gla"); player.charaWork.battleSave.skillLevel[Player.CLASSID_GLA - 1] = reader.GetInt16("gla");
player.charaWork.battleSave.skillLevel[Player.CLASSID_MRD - 1] = reader.GetInt16("mrd"); player.charaWork.battleSave.skillLevel[Player.CLASSID_MRD - 1] = reader.GetInt16("mrd");
player.charaWork.battleSave.skillLevel[Player.CLASSID_ARC - 1] = reader.GetInt16("arc"); player.charaWork.battleSave.skillLevel[Player.CLASSID_ARC - 1] = reader.GetInt16("arc");
@ -966,7 +967,7 @@ namespace FFXIVClassic_Map_Server
while (reader.Read()) while (reader.Read())
{ {
int index = reader.GetUInt16(0); int index = reader.GetUInt16(0);
player.charaWork.command[index+32] = reader.GetUInt32(1); player.charaWork.command[index + 32] = reader.GetUInt32(1);
player.charaWork.parameterSave.commandSlot_recastTime[index] = reader.GetUInt32(2); player.charaWork.parameterSave.commandSlot_recastTime[index] = reader.GetUInt32(2);
} }
} }
@ -1121,7 +1122,7 @@ namespace FFXIVClassic_Map_Server
{ {
ushort equipSlot = reader.GetUInt16(0); ushort equipSlot = reader.GetUInt16(0);
ulong uniqueItemId = reader.GetUInt16(1); ulong uniqueItemId = reader.GetUInt16(1);
InventoryItem item = player.GetInventory(Inventory.NORMAL).GetItemById(uniqueItemId); InventoryItem item = player.GetInventory(Inventory.NORMAL).GetItemByUniqueId(uniqueItemId);
equipment[equipSlot] = item; equipment[equipSlot] = item;
} }
} }
@ -1345,7 +1346,7 @@ namespace FFXIVClassic_Map_Server
{ {
conn.Open(); conn.Open();
string query = @" string query = @"
UPDATE characters_inventory UPDATE characters_inventory
SET quantity = @quantity SET quantity = @quantity
WHERE characterId = @charId AND slot = @slot AND inventoryType = @type; WHERE characterId = @charId AND slot = @slot AND inventoryType = @type;
@ -1538,7 +1539,6 @@ namespace FFXIVClassic_Map_Server
return cheevosPacket.BuildPacket(player.actorId); return cheevosPacket.BuildPacket(player.actorId);
} }
public static bool CreateLinkshell(Player player, string lsName, ushort lsCrest) public static bool CreateLinkshell(Player player, string lsName, ushort lsCrest)
{ {
bool success = false; bool success = false;
@ -1615,6 +1615,315 @@ namespace FFXIVClassic_Map_Server
} }
} }
} }
public static bool SaveSupportTicket(GMSupportTicketPacket gmTicket, string playerName)
{
string query;
MySqlCommand cmd;
bool wasError = false;
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
query = @"
INSERT INTO supportdesk_tickets
(name, title, body, langCode)
VALUES
(@name, @title, @body, @langCode)";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@name", playerName);
cmd.Parameters.AddWithValue("@title", gmTicket.ticketTitle);
cmd.Parameters.AddWithValue("@body", gmTicket.ticketBody);
cmd.Parameters.AddWithValue("@langCode", gmTicket.langCode);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
wasError = true;
}
finally
{
conn.Dispose();
}
}
return wasError;
}
public static bool isTicketOpen(string playerName)
{
bool isOpen = false;
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
SELECT
isOpen
FROM supportdesk_tickets
WHERE name = @name
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@name", playerName);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
isOpen = reader.GetBoolean(0);
}
}
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
return isOpen;
}
public static void closeTicket(string playerName)
{
bool isOpen = false;
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
UPDATE
supportdesk_tickets
SET isOpen = 0
WHERE name = @name
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@name", playerName);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
}
public static string[] getFAQNames(uint langCode = 1)
{
string[] faqs = null;
List<string> raw = new List<string>();
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
SELECT
title
FROM supportdesk_faqs
WHERE languageCode = @langCode
ORDER BY slot
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@langCode", langCode);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
string label = reader.GetString(0);
raw.Add(label);
}
}
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
faqs = raw.ToArray();
}
}
return faqs;
}
public static string getFAQBody(uint slot, uint langCode = 1)
{
string body = string.Empty;
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
SELECT
body
FROM supportdesk_faqs
WHERE slot=@slot and languageCode=@langCode";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@slot", slot);
cmd.Parameters.AddWithValue("@langCode", langCode);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
body = reader.GetString(0);
}
}
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
return body;
}
public static string[] getIssues(uint lanCode = 1)
{
string[] issues = null;
List<string> raw = new List<string>();
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
SELECT
title
FROM supportdesk_issues
ORDER BY slot";
MySqlCommand cmd = new MySqlCommand(query, conn);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
string label = reader.GetString(0);
raw.Add(label);
}
}
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
issues = raw.ToArray();
}
}
return issues;
}
public static void IssuePlayerChocobo(Player player, byte appearanceId, string name)
{
string query;
MySqlCommand cmd;
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
query = @"
INSERT INTO characters_chocobo
(characterId, hasChocobo, chocoboAppearance, chocoboName)
VALUES
(@characterId, @hasChocobo, @chocoboAppearance, @chocoboName)
ON DUPLICATE KEY UPDATE
hasChocobo=@hasChocobo, chocoboAppearance=@chocoboAppearance, chocoboName=@chocoboName";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@characterId", player.actorId);
cmd.Parameters.AddWithValue("@hasChocobo", 1);
cmd.Parameters.AddWithValue("@chocoboAppearance", appearanceId);
cmd.Parameters.AddWithValue("@chocoboName", name);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
}
public static void ChangePlayerChocoboAppearance(Player player, byte appearanceId)
{
string query;
MySqlCommand cmd;
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
query = @"
UPDATE characters_chocobo
SET
chocoboAppearance=@chocoboAppearance
WHERE
characterId = @characterId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@characterId", player.actorId);
cmd.Parameters.AddWithValue("@chocoboAppearance", appearanceId);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
}
} }
} }

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props')" /> <Import Project="..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props') AND '$(OS)' == 'Windows_NT'" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props') AND '$(OS)' == 'Windows_NT'" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -223,19 +223,19 @@
<Compile Include="packets\send\groups\ContentMembersX64Packet.cs" /> <Compile Include="packets\send\groups\ContentMembersX64Packet.cs" />
<Compile Include="packets\send\groups\GroupMembersX64Packet.cs" /> <Compile Include="packets\send\groups\GroupMembersX64Packet.cs" />
<Compile Include="packets\send\groups\SynchGroupWorkValuesPacket.cs" /> <Compile Include="packets\send\groups\SynchGroupWorkValuesPacket.cs" />
<Compile Include="packets\send\player\InfoRequestResponsePacket.cs" /> <Compile Include="packets\send\player\GenericDataPacket.cs" />
<Compile Include="packets\send\player\SendAchievementRatePacket.cs" /> <Compile Include="packets\send\player\SendAchievementRatePacket.cs" />
<Compile Include="packets\send\player\SetCurrentJobPacket.cs" /> <Compile Include="packets\send\player\SetCurrentJobPacket.cs" />
<Compile Include="packets\send\player\SetCurrentMountGoobbuePacket.cs" /> <Compile Include="packets\send\player\SetCurrentMountGoobbuePacket.cs" />
<Compile Include="packets\send\player\SetCurrentMountChocoboPacket.cs" /> <Compile Include="packets\send\player\SetCurrentMountChocoboPacket.cs" />
<Compile Include="packets\send\player\SetGrandCompanyPacket.cs" /> <Compile Include="packets\send\player\SetGrandCompanyPacket.cs" />
<Compile Include="packets\send\actor\SetActorNamePacket.cs" /> <Compile Include="packets\send\Actor\SetActorNamePacket.cs" />
<Compile Include="packets\send\actor\SetActorPropetyPacket.cs" /> <Compile Include="packets\send\Actor\SetActorPropetyPacket.cs" />
<Compile Include="packets\send\actor\SetActorSpeedPacket.cs" /> <Compile Include="packets\send\Actor\SetActorSpeedPacket.cs" />
<Compile Include="packets\send\actor\SetActorStatePacket.cs" /> <Compile Include="packets\send\Actor\SetActorStatePacket.cs" />
<Compile Include="packets\send\actor\SetActorTargetAnimatedPacket.cs" /> <Compile Include="packets\send\Actor\SetActorTargetAnimatedPacket.cs" />
<Compile Include="packets\send\actor\SetActorTargetPacket.cs" /> <Compile Include="packets\send\Actor\SetActorTargetPacket.cs" />
<Compile Include="packets\send\actor\SetActorStatusAllPacket.cs" /> <Compile Include="packets\send\Actor\SetActorStatusAllPacket.cs" />
<Compile Include="packets\send\login\0x2Packet.cs" /> <Compile Include="packets\send\login\0x2Packet.cs" />
<Compile Include="packets\send\actor\AddActorPacket.cs" /> <Compile Include="packets\send\actor\AddActorPacket.cs" />
<Compile Include="packets\send\actor\MoveActorToPositionPacket.cs" /> <Compile Include="packets\send\actor\MoveActorToPositionPacket.cs" />

View file

@ -347,3 +347,4 @@ namespace FFXIVClassic_Map_Server
} }
} }

View file

@ -1116,7 +1116,5 @@ namespace FFXIVClassic_Map_Server
else else
return null; return null;
} }
} }
} }

View file

@ -1,6 +1,5 @@
using FFXIVClassic_Map_Server; using FFXIVClassic_Map_Server;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
@ -282,6 +281,7 @@ namespace FFXIVClassic_Map_Server.Actors
} }
} }
} }
//Remove players if isolation zone //Remove players if isolation zone
if (isIsolated) if (isIsolated)
{ {
@ -410,7 +410,6 @@ namespace FFXIVClassic_Map_Server.Actors
Npc npc = new Npc(mActorList.Count + 1, actorClass, location.uniqueId, this, location.x, location.y, location.z, location.rot, location.state, location.animId, null); Npc npc = new Npc(mActorList.Count + 1, actorClass, location.uniqueId, this, location.x, location.y, location.z, location.rot, location.state, location.animId, null);
npc.LoadEventConditions(actorClass.eventConditions); npc.LoadEventConditions(actorClass.eventConditions);
AddActorToZone(npc); AddActorToZone(npc);

View file

@ -52,8 +52,8 @@ namespace FFXIVClassic_Map_Server.Actors
LoadNpcAppearance(actorClass.actorClassId); LoadNpcAppearance(actorClass.actorClassId);
this.classPath = actorClass.classPath; className = actorClass.classPath.Substring(actorClass.classPath.LastIndexOf("/") + 1);
className = classPath.Substring(classPath.LastIndexOf("/")+1); this.classPath = String.Format("{0}/{1}", actorClass.classPath.Substring(0, actorClass.classPath.LastIndexOf('/')).ToLower(), className);
charaWork.battleSave.potencial = 1.0f; charaWork.battleSave.potencial = 1.0f;

View file

@ -46,11 +46,21 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
return null; return null;
} }
public InventoryItem GetItemById(ulong itemId) public InventoryItem GetItemByUniqueId(ulong uniqueItemId)
{ {
foreach (InventoryItem item in list) foreach (InventoryItem item in list)
{ {
if (item.uniqueId == itemId) if (item.uniqueId == uniqueItemId)
return item;
}
return null;
}
public InventoryItem GetItemByCatelogId(ulong catelogId)
{
foreach (InventoryItem item in list)
{
if (item.itemId == catelogId)
return item; return item;
} }
return null; return null;

View file

@ -1,5 +1,4 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.chara.player; using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.actors.director; using FFXIVClassic_Map_Server.actors.director;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
@ -8,6 +7,9 @@ using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send; using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.events; using FFXIVClassic_Map_Server.packets.send.events;
using FFXIVClassic_Map_Server.packets.send.actor.events;
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using FFXIVClassic_Map_Server.packets.send.events;
using FFXIVClassic_Map_Server.packets.send.player; using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
using System; using System;
@ -340,6 +342,7 @@ namespace FFXIVClassic_Map_Server.Actors
subpackets.Add(SetHasGoobbuePacket.BuildPacket(actorId, hasGoobbue)); subpackets.Add(SetHasGoobbuePacket.BuildPacket(actorId, hasGoobbue));
subpackets.Add(SetAchievementPointsPacket.BuildPacket(actorId, achievementPoints)); subpackets.Add(SetAchievementPointsPacket.BuildPacket(actorId, achievementPoints));
subpackets.Add(Database.GetLatestAchievements(this)); subpackets.Add(Database.GetLatestAchievements(this));
subpackets.Add(Database.GetAchievementsPacket(this)); subpackets.Add(Database.GetAchievementsPacket(this));
} }
@ -543,6 +546,7 @@ namespace FFXIVClassic_Map_Server.Actors
playerSession.QueuePacket(worldMasterSpawn); playerSession.QueuePacket(worldMasterSpawn);
//Inn Packets (Dream, Cutscenes, Armoire) //Inn Packets (Dream, Cutscenes, Armoire)
if (zone.isInn) if (zone.isInn)
{ {
SetCutsceneBookPacket cutsceneBookPacket = new SetCutsceneBookPacket(); SetCutsceneBookPacket cutsceneBookPacket = new SetCutsceneBookPacket();
@ -569,7 +573,6 @@ namespace FFXIVClassic_Map_Server.Actors
if (currentContentGroup != null) if (currentContentGroup != null)
currentContentGroup.SendGroupPackets(playerSession); currentContentGroup.SendGroupPackets(playerSession);
} }
private void SendRemoveInventoryPackets(List<ushort> slots) private void SendRemoveInventoryPackets(List<ushort> slots)
@ -600,6 +603,7 @@ namespace FFXIVClassic_Map_Server.Actors
} }
public void QueuePacket(SubPacket packet) public void QueuePacket(SubPacket packet)
{ {
playerSession.QueuePacket(packet); playerSession.QueuePacket(packet);
} }
@ -987,6 +991,7 @@ namespace FFXIVClassic_Map_Server.Actors
else else
{ {
ItemData item = Server.GetItemGamedata(invItem.itemId); ItemData item = Server.GetItemGamedata(invItem.itemId);
if (item is EquipmentItem) if (item is EquipmentItem)
{ {
EquipmentItem eqItem = (EquipmentItem)item; EquipmentItem eqItem = (EquipmentItem)item;
@ -1021,7 +1026,6 @@ namespace FFXIVClassic_Map_Server.Actors
} }
Database.SavePlayerAppearance(this); Database.SavePlayerAppearance(this);
BroadcastPacket(CreateAppearancePacket(), true); BroadcastPacket(CreateAppearancePacket(), true);
} }
@ -1033,6 +1037,14 @@ namespace FFXIVClassic_Map_Server.Actors
return null; return null;
} }
public int GetCurrentGil()
{
if (GetInventory(Inventory.CURRENCY).HasItem(1000001))
return GetInventory(Inventory.CURRENCY).GetItemByCatelogId(1000001).quantity;
else
return 0;
}
public Actor GetActorInInstance(uint actorId) public Actor GetActorInInstance(uint actorId)
{ {
foreach (Actor a in playerSession.actorInstanceList) foreach (Actor a in playerSession.actorInstanceList)
@ -1546,7 +1558,7 @@ namespace FFXIVClassic_Map_Server.Actors
public void SendDataPacket(params object[] parameters) public void SendDataPacket(params object[] parameters)
{ {
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters); List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
SubPacket spacket = InfoRequestResponsePacket.BuildPacket(actorId, lParams); SubPacket spacket = GenericDataPacket.BuildPacket(actorId, lParams);
spacket.DebugPrintSubPacket(); spacket.DebugPrintSubPacket();
QueuePacket(spacket); QueuePacket(spacket);
} }
@ -1702,5 +1714,18 @@ namespace FFXIVClassic_Map_Server.Actors
LuaEngine.GetInstance().CallLuaFunction(this, this, "OnUpdate", true, delta); LuaEngine.GetInstance().CallLuaFunction(this, this, "OnUpdate", true, delta);
} }
public void IssueChocobo(byte appearanceId, string nameResponse)
{
Database.IssuePlayerChocobo(this, appearanceId, nameResponse);
hasChocobo = true;
chocoboAppearance = appearanceId;
chocoboName = nameResponse;
}
public void ChangeChocoboAppearance(byte appearanceId)
{
Database.ChangePlayerChocoboAppearance(this, appearanceId);
chocoboAppearance = appearanceId;
}
} }
} }

View file

@ -6,7 +6,7 @@ using FFXIVClassic.Common;
namespace FFXIVClassic_Map_Server.packets.send.player namespace FFXIVClassic_Map_Server.packets.send.player
{ {
class InfoRequestResponsePacket class GenericDataPacket
{ {
public const ushort OPCODE = 0x0133; public const ushort OPCODE = 0x0133;
public const uint PACKET_SIZE = 0xE0; public const uint PACKET_SIZE = 0xE0;

View file

@ -15,17 +15,100 @@ eventTalkStepBreak(player) - Finishes talkTurn and says a goodbye
require ("global") require ("global")
local gcIssuances = {
[1500006] = 2001004,
[1500061] = 2001005,
[1000840] = 2001006
};
local startAppearances = {
[1500006] = CHOCOBO_LIMSA1,
[1500061] = CHOCOBO_GRIDANIA1,
[1000840] = CHOCOBO_ULDAH1
};
local cityExits = {
[1500006] = 15,
[1500061] = 14,
[1000840] = 16
};
function init(npc) function init(npc)
return false, false, 0, 0; return false, false, 0, 0;
end end
function onEventStarted(player, npc, triggerName) function onEventStarted(player, npc, triggerName)
callClientFunction(player, "eventTalkWelcome", player); --callClientFunction(player, "eventTalkWelcome", player);
callClientFunction(player, "eventAskMainMenu", player, 20, true, true, true, true, 4); --callClientFunction(player, "eventAskMainMenu", player, 20, true, true, true, true, 4);
--callClientFunction(player, "eventTalkMyChocobo", player); --callClientFunction(player, "eventTalkMyChocobo", player);
--callClientFunction(player, "eventSetChocoboName", false); --callClientFunction(player, "eventSetChocoboName", false);
--callClientFunction(player, "eventAfterChocoboName", player); --callClientFunction(player, "eventAfterChocoboName", player);
local curLevel = 20; -- TODO: pull from character
local hasIssuance = player:GetInventory(INVENTORY_KEYITEMS):HasItem(gcIssuances[npc:GetActorClassId()]);
local hasChocobo = player.hasChocobo;
if (player.isGM and hasChocobo == false) then -- Let GMs auto have the issuance for debugging
hasIssuance = true;
end
local rentPrice = 800;
local hasFunds = (player:GetCurrentGil() >= rentPrice);
callClientFunction(player, "eventTalkWelcome", player);
local menuChoice = callClientFunction(player, "eventAskMainMenu", player, curLevel, hasFunds, hasIssuance, true, true, player.chocoboAppearance);
if (menuChoice == 1) then -- Issuance option
callClientFunction(player, "eventTalkMyChocobo", player);
local nameResponse = callClientFunction(player, "eventSetChocoboName", true);
if (nameResponse == "") then -- Cancel Chocobo naming
callClientFunction(player, "eventCancelChocoboName", player);
callClientFunction(player, "eventTalkStepBreak", player);
player:EndEvent();
return;
else
local appearance = startAppearances[npc:GetActorClassId()];
player:IssueChocobo(appearance, nameResponse);
callClientFunction(player, "eventAfterChocoboName", player);
mountChocobo(player);
GetWorldManager():DoZoneChange(player, cityExits[npc:GetActorClassId()]);
player:SendGameMessage(player, GetWorldMaster(), 25248, 0x20, 2001007);
player:SendDataPacket("attention", GetWorldMaster(), "", 25248, 2001007);
if (player:GetInventory(INVENTORY_KEYITEMS):HasItem(2001007) == false) then
player:GetInventory(INVENTORY_KEYITEMS):AddItem(2001007);
end
player:GetInventory(INVENTORY_KEYITEMS):RemoveItem(gcIssuances[npc:GetActorClassId()], 1);
player:EndEvent();
return;
end
elseif(menuChoice == 2) then -- Summon Bird
mountChocobo(player);
GetWorldManager():DoZoneChange(player, cityExits[npc:GetActorClassId()]);
elseif(menuChoice == 3) then -- Change Barding
callClientFunction(player, "eventTalkStepBreak", player);
elseif(menuChoice == 5) then -- Rent Bird
issueRentalChocobo(player);
else
callClientFunction(player, "eventTalkStepBreak", player);
end
player:EndEvent(); player:EndEvent();
end end
function mountChocobo(player)
player:SendChocoboAppearance();
player:SetMountState(1);
player:ChangeSpeed(0.0, 5.0, 10.0);
player:ChangeState(15);
end
function issueRentalChocobo(player)
--TODO: Write issue rental chocobo code
end

View file

@ -2,11 +2,16 @@ require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "sssss", parameters = "ssss",
description = "removes <currency> <qty> from <target>, currency is removed from user if <target> is nil", description =
[[
Removes currency <qty> from player or <targetname>
!delcurrency <item> <qty> |
!delcurrency <item> <qty> <targetname> |
]],
} }
function onTrigger(player, argc, currency, qty, location, name, lastName) function onTrigger(player, argc, currency, qty, name, lastName)
local sender = "[delcurrency] "; local sender = "[delcurrency] ";
if name then if name then
@ -19,12 +24,11 @@ function onTrigger(player, argc, currency, qty, location, name, lastName)
if player then if player then
currency = tonumber(currency) or nil; currency = tonumber(currency) or nil;
qty = 1; qty = tonumber(qty) or 1;
location = INVENTORY_CURRENCY;
local removed = player:GetInventory(location):removecurrency(currency, qty); local removed = player:GetInventory(INVENTORY_CURRENCY):RemoveItem(currency, qty);
local messageID = MESSAGE_TYPE_SYSTEM_ERROR; local messageID = MESSAGE_TYPE_SYSTEM_ERROR;
local message = "unable to remove currency"; local message = "Attempting to remove currency" -- "unable to remove currency";
if currency and removed then if currency and removed then
message = string.format("removed currency %u from %s", currency, player:GetName()); message = string.format("removed currency %u from %s", currency, player:GetName());

View file

@ -3,11 +3,18 @@ require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "sssss", parameters = "sssss",
description = "removes <item> <qty> from <location> for <target>. <qty> and <location> are optional, item is removed from user if <target> is nil", description =
[[
Removes <item> <qty> from <location> for player or <targetname>.
!delitem <item> <qty> |
!delitem <item> <qty> <location> |
!delitem <item> <qty> <location> <targetname> |
]],
} }
function onTrigger(player, argc, item, qty, location, name, lastName) function onTrigger(player, argc, item, qty, location, name, lastName)
local sender = "[delitem] "; local sender = "[delitem] ";
local messageID = MESSAGE_TYPE_SYSTEM_ERROR;
if name then if name then
if lastName then if lastName then
@ -20,18 +27,29 @@ function onTrigger(player, argc, item, qty, location, name, lastName)
if player then if player then
item = tonumber(item) or nil; item = tonumber(item) or nil;
qty = tonumber(qty) or 1; qty = tonumber(qty) or 1;
location = tonumber(itemtype) or INVENTORY_NORMAL;
local removed = player:GetInventory(location):removeItem(item, qty); if location then
local messageID = MESSAGE_TYPE_SYSTEM_ERROR; location = tonumber(location) or _G[string.upper(location)];
local message = "unable to remove item";
if item and removed then if location == nil then
message = string.format("removed item %u from %s", item, player:GetName()); player:SendMessage(messageID, sender, "Unknown item location.");
end return;
player:SendMessage(messageID, sender, message); end;
print(message); else
location = INVENTORY_NORMAL;
end;
local removed = player:GetInventory(location):RemoveItem(item, qty);
if removed then -- RemoveItem() currently returns nothing for verification, this statement can't work
message = string.format("Removed item %u of kind %u to %s", item, location, player:GetName());
end;
else else
print(sender.."unable to remove item, ensure player name is valid."); print(sender.."[giveitem] Unable to remove item, ensure player name is valid.");
return;
end; end;
local message = string.format("Attempting to remove item %u of kind %u from %s", item, location, player:GetName());
player:SendMessage(messageID, sender, message);
print(message);
end; end;

View file

@ -3,7 +3,12 @@ require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "ssss", parameters = "ssss",
description = "removes <keyitem> <qty> from <target>, keyitem is removed from user if <target> is nil", description =
[[
Removes <keyitem> from player or <targetname>.
!delkeyitem <keyitem> |
!delkeyitem <keyitem> <target name> |
]],
} }
function onTrigger(player, argc, keyitem, qty, name, lastName) function onTrigger(player, argc, keyitem, qty, name, lastName)
@ -19,16 +24,16 @@ function onTrigger(player, argc, keyitem, qty, name, lastName)
if player then if player then
keyitem = tonumber(keyitem) or nil; keyitem = tonumber(keyitem) or nil;
qty = 1; qty = tonumber(qty) or 1;
location = INVENTORY_KEYITEMS; local location = INVENTORY_KEYITEMS;
local removed = player:GetInventory(location):removeItem(item, qty); local removed = player:GetInventory(location):RemoveItem(keyitem, qty);
local messageID = MESSAGE_TYPE_SYSTEM_ERROR; local messageID = MESSAGE_TYPE_SYSTEM_ERROR;
local message = "unable to remove keyitem"; local message = "Attempting to remove keyitem" -- "unable to remove keyitem";
if keyitem and removed then if removed then
message = string.format("removed keyitem %u from %s", keyitem, player:GetName()); message = string.format("removed keyitem %u from %s", keyitem, player:GetName());
end end;
player:SendMessage(messageID, sender, message); player:SendMessage(messageID, sender, message);
print(message); print(message);
else else

View file

@ -2,11 +2,16 @@ require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "sss", parameters = "ssss",
description = "adds <currency> to self or <target>.", description =
[[
Adds currency <qty> to player or <targetname>
!addcurrency <item> <qty> |
!addcurrency <item> <qty> <targetname> |
]],
} }
function onTrigger(player, argc, currency, name, lastName) function onTrigger(player, argc, currency, qty, name, lastName)
local sender = "[givecurrency] "; local sender = "[givecurrency] ";
if name then if name then
@ -19,10 +24,10 @@ function onTrigger(player, argc, currency, name, lastName)
if player then if player then
currency = tonumber(currency) or nil; currency = tonumber(currency) or nil;
qty = 1; qty = tonumber(qty) or 1;
location = INVENTORY_CURRENCY; location = INVENTORY_CURRENCY;
local added = player:GetInventory(location):AddItem(currency, qty); local added = player:GetInventory(location):AddItem(currency, qty, 1);
local messageID = MESSAGE_TYPE_SYSTEM_ERROR; local messageID = MESSAGE_TYPE_SYSTEM_ERROR;
local message = "unable to add currency"; local message = "unable to add currency";

View file

@ -3,11 +3,19 @@ require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "sssss", parameters = "sssss",
description = "adds <item> <qty> to <location> for <target>. <qty> and <location> are optional, item is added to user if <target> is nil", description =
[[
Adds <item> <qty> to <location> for player or <targetname>.
!giveitem <item> <qty> |
!giveitem <item> <qty> <location> |
!giveitem <item> <qty> <location> <targetname> |
]],
} }
function onTrigger(player, argc, item, qty, location, name, lastName) function onTrigger(player, argc, item, qty, location, name, lastName)
local sender = "[giveitem] "; local sender = "[giveitem] ";
local messageID = MESSAGE_TYPE_SYSTEM_ERROR;
local message = string.format("Unable to add item %u", item);
if name then if name then
if lastName then if lastName then
@ -20,17 +28,28 @@ function onTrigger(player, argc, item, qty, location, name, lastName)
if player then if player then
item = tonumber(item) or nil; item = tonumber(item) or nil;
qty = tonumber(qty) or 1; qty = tonumber(qty) or 1;
location = tonumber(itemtype) or INVENTORY_NORMAL;
local added = player:GetInventory(location):AddItem(item, qty);
local messageID = MESSAGE_TYPE_SYSTEM_ERROR;
local message = "unable to add item";
if item and added then if location then
message = string.format("added item %u to %s", item, player:GetName()); location = tonumber(location) or _G[string.upper(location)];
end
player:SendMessage(messageID, sender, message); if not location then
print(message); player:SendMessage(messageID, sender, "Unknown item location.");
return;
end;
else
location = INVENTORY_NORMAL;
end;
local added = player:getInventory(location):addItem(item, qty, 1);
if added then
message = string.format("Added item %u of kind %u to %s", item, location, player:GetName());
end;
else else
print(sender.."unable to add item, ensure player name is valid."); print(sender.."[giveitem] Unable to add item, ensure player name is valid.");
return;
end; end;
player:SendMessage(messageID, sender, message);
print(message);
end; end;

View file

@ -3,7 +3,12 @@ require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "sss", parameters = "sss",
description = "adds <keyitem> to self or <target>.", description =
[[
Adds <keyitem> to player or <targetname>.
!giveitem <keyitem> |
!giveitem <keyitem> <target name> |
]],
} }
function onTrigger(player, argc, keyitem, name, lastName) function onTrigger(player, argc, keyitem, name, lastName)
@ -22,7 +27,7 @@ function onTrigger(player, argc, keyitem, name, lastName)
qty = 1; qty = 1;
location = INVENTORY_KEYITEMS; location = INVENTORY_KEYITEMS;
local added = player:GetInventory(location):AddItem(keyitem, qty); local added = player:GetInventory(location):AddItem(keyitem, qty, 1);
local messageID = MESSAGE_TYPE_SYSTEM_ERROR; local messageID = MESSAGE_TYPE_SYSTEM_ERROR;
local message = "unable to add keyitem"; local message = "unable to add keyitem";

View file

@ -1,18 +1,31 @@
require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "sssss", parameters = "sssss",
description = "changes appearance for equipment in <slot>. Parameters: <slot> <wId> <eId> <vId> <cId>, (idk what any of those mean either)", description =
[[
Changes appearance for equipment with given parameters.
!graphic <slot> <wID> <eID> <vID> <vID>
]],
} }
function onTrigger(player, argc, slot, wId, eId, vId, cId) function onTrigger(player, argc, slot, wId, eId, vId, cId)
local messageID = MESSAGE_TYPE_SYSTEM_ERROR;
local sender = "[graphic] ";
slot = tonumber(slot) or 0; slot = tonumber(slot) or 0;
wId = tonumber(wId) or 0; wId = tonumber(wId) or 0;
eId = tonumber(eId) or 0; eId = tonumber(eId) or 0;
vId = tonumber(vId) or 0; vId = tonumber(vId) or 0;
cId = tonumber(cId) or 0; cId = tonumber(cId) or 0;
if player then if player and argc > 0 then
player:GraphicChange(slot, wId, eId, vId, cId); player:GraphicChange(slot, wId, eId, vId, cId);
player:SendAppearance(); player:SendAppearance();
player:SendMessage(messageID, sender, string.format("Changing appearance on slot %u", slot));
else
player:SendMessage(messageID, sender, "No parameters sent! Usage: "..properties.description);
end; end;
end; end;

View file

@ -1,7 +1,11 @@
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "s", parameters = "s",
description = "plays music <id> to player", description =
[[
Plays music <id> to player.
!music <id>
]],
} }
function onTrigger(player, argc, music) function onTrigger(player, argc, music)

View file

@ -1,7 +1,12 @@
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "ssss", parameters = "ssss",
description = "<name> <target name>", description =
[[
Sends a custom <packet> to player or <targetname>
!sendpacket <packet> |
!sendpacket <packet> <targetname> |
]],
} }
function onTrigger(player, argc, path, name, lastName) function onTrigger(player, argc, path, name, lastName)

View file

@ -1,18 +1,36 @@
require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "sss", parameters = "sss",
description = "<stop> <walk> <run> speed", description =
[[
Set movement speed for player. Enter no value to reset to default.
!speed <run> |
!speed <stop> <walk> <run> |
]]
} }
function onTrigger(player, argc, stop, walk, run) function onTrigger(player, argc, stop, walk, run)
stop = tonumber(stop) or 0;
walk = tonumber(walk) or 2; if argc == 1 then
run = tonumber(run) or 5; s = 0;
if argc == 3 then w = (tonumber(stop) / 2);
player:ChangeSpeed(stop, walk, run, run); r = tonumber(stop);
elseif argc == 1 then player:ChangeSpeed(s, w, r);
player:ChangeSpeed(0, stop/2, stop, stop); player:SendMessage(MESSAGE_TYPE_SYSTEM_ERROR, "[speed]", string.format("Speed set to 0/%u/%u", w,r));
else elseif argc == 3 then
player:ChangeSpeed(0,2,5,5); stop = tonumber(stop) or 0;
walk = tonumber(walk) or 2;
run = tonumber(run) or 5;
if argc == 3 then
player:ChangeSpeed(stop, walk, run, run);
elseif argc == 1 then
player:ChangeSpeed(0, stop/2, stop, stop);
else
player:ChangeSpeed(0,2,5,5);
end
end end
end end

View file

@ -5,9 +5,10 @@ properties = {
parameters = "sssssss", parameters = "sssssss",
description = description =
[[ [[
<zone> | Warp player or <targetname> to a location from a list, or enter a zoneID with coordinates.
<zone> <x> <y> <z> | !warp <spawn list> |
<zone> <x> <y> <z> <privateArea> <target name>. !warp <zone> <x> <y> <z> |
!warp <zone> <x> <y> <z> <privateArea> <targetname> |
]], ]],
} }
@ -47,6 +48,7 @@ function onTrigger(player, argc, p1, p2, p3, p4, privateArea, name, lastName)
local z = tonumber(applyPositionOffset(p3, player_z)) or player_z; local z = tonumber(applyPositionOffset(p3, player_z)) or player_z;
player:SendMessage(messageID, sender, string.format("setting coordinates X:%d Y:%d Z:%d within current zone (%d)", x, y, z, player_zone)); player:SendMessage(messageID, sender, string.format("setting coordinates X:%d Y:%d Z:%d within current zone (%d)", x, y, z, player_zone));
worldManager:DoPlayerMoveInZone(player, x, y, z, player_rot, 0x00); worldManager:DoPlayerMoveInZone(player, x, y, z, player_rot, 0x00);
else else
local zone = tonumber(applyPositionOffset(p1, player_zone)) or player_zone; local zone = tonumber(applyPositionOffset(p1, player_zone)) or player_zone;
@ -65,9 +67,10 @@ end;
function applyPositionOffset(str, offset) function applyPositionOffset(str, offset)
local s = str; local s = str;
print(s);
if s:find("@") then if s:find("@") then
s = tonumber(s:sub(s:find("@") + 1, s:len())) + offset; s = tonumber(s:sub(s:find("@") + 1, s:len()));
if s then s = s + offset end;
end end
print(s);
return s; return s;
end; end;

View file

@ -3,7 +3,12 @@ require("global");
properties = { properties = {
permissions = 0, permissions = 0,
parameters = "ssss", parameters = "ssss",
description = "usage: <id> <updateTime> <zonewide>.", description =
[[
Change the weather visual to <id> and optional <transition> for player.
!weather <id> |
!weather <id> <transition> |
]],
} }
function onTrigger(player, argc, weather, updateTime, zonewide) function onTrigger(player, argc, weather, updateTime, zonewide)
@ -16,12 +21,14 @@ function onTrigger(player, argc, weather, updateTime, zonewide)
weather = tonumber(weather) or 0; weather = tonumber(weather) or 0;
updateTime = tonumber(updateTime) or 0; updateTime = tonumber(updateTime) or 0;
zonewide = tonumber(zonewide) or 0; zonewide = tonumber(zonewide) or 0;
message = "changed weather to %u "; message = string.format("changed weather to %u ", weather);
if zonewide ~= 0 then if zonewide ~= 0 then
message = string.format(message.."for zone %u", player:GetZoneID()); message = string.format(message.."for zone %u", player:GetZoneID());
else else
message = message..player:GetName(); message = message..player:GetName();
end; end;
-- weatherid, updateTime -- weatherid, updateTime
player:GetZone():ChangeWeather(weather, updateTime, player, zonewide ~= 0); player:GetZone():ChangeWeather(weather, updateTime, player, zonewide ~= 0);
player:SendMessage(messageID, sender, message); player:SendMessage(messageID, sender, message);

View file

@ -51,34 +51,30 @@ INVENTORY_KEYITEMS = 0x0064; --Max 0x500
INVENTORY_EQUIPMENT = 0x00FE; --Max 0x23 INVENTORY_EQUIPMENT = 0x00FE; --Max 0x23
INVENTORY_EQUIPMENT_OTHERPLAYER = 0x00F9; --Max 0x23 INVENTORY_EQUIPMENT_OTHERPLAYER = 0x00F9; --Max 0x23
-- NPC LS -- CHOCOBO APPEARANCE
NPCLS_GONE = 0; CHOCOBO_NORMAL = 0;
NPCLS_INACTIVE = 1;
NPCLS_ACTIVE = 2; CHOCOBO_LIMSA1 = 0x1;
NPCLS_ALERT = 3; CHOCOBO_LIMSA2 = 0x2;
CHOCOBO_LIMSA3 = 0x3;
CHOCOBO_LIMSA4 = 0x4;
CHOCOBO_GRIDANIA1 = 0x1F;
CHOCOBO_GRIDANIA2 = 0x20;
CHOCOBO_GRIDANIA3 = 0x21;
CHOCOBO_GRIDANIA4 = 0x22;
CHOCOBO_ULDAH1 = 0x3D;
CHOCOBO_ULDAH2 = 0x3E;
CHOCOBO_ULDAH3 = 0x3F;
CHOCOBO_ULDAH4 = 0x40;
--UTILS --UTILS
function kickEventContinue(player, actor, trigger, ...)
player:kickEvent(actor, trigger, ...);
return coroutine.yield("_WAIT_EVENT", player);
end
function callClientFunction(player, functionName, ...) function callClientFunction(player, functionName, ...)
player:RunEventFunction(functionName, ...); player:RunEventFunction(functionName, ...);
return coroutine.yield("_WAIT_EVENT", player); result = coroutine.yield();
end return result;
function wait(seconds)
return coroutine.yield("_WAIT_TIME", seconds);
end
function waitForSignal(signal)
return coroutine.yield("_WAIT_SIGNAL", signal);
end
function sendSignal(signal)
GetLuaInstance():OnSignal(signal);
end end
function printf(s, ...) function printf(s, ...)

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithL'tandhaa_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithLtandhaa_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithNonco_menanco_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithNoncomananco_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_private_hill_001", nil, nil, nil);
player:endEvent();
end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithTask_board_001", nil, nil, nil);
player:endEvent();
end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithAubrenard (check cnstctr)_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithAUBRENARD_100", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithDrystbrod_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithDyrstbrod_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithEldid_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "downTownTalk", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithEnie_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkEnie_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithGagaroon_001", nil, nil, nil);
player:endEvent();
end

View file

@ -46,8 +46,8 @@ function onEventStarted(player, npc)
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithKhumamoshroca_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithKhumamoshroca_001", nil, nil, nil);
end end
player:endEvent(); player:endEvent();
end end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithLouisoix_001", nil, nil, nil);
player:endEvent();
end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithMaisenta_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithGuildleveClientG_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithProsperlain_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "tribeTalk", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithPukiki_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithGuildleveClientG_002", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -1,7 +1,7 @@
require ("global") require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("Spl000");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_lieutenant_marette_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "processEventELNAURE", 1,1,1);
player:endEvent(); player:endEvent();
end end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_private_carver_001", nil, nil, nil);
player:endEvent();
end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_private_holmes_001", nil, nil, nil);
player:endEvent();
end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_private_kirk_001", nil, nil, nil);
player:endEvent();
end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_private_stone_001", nil, nil, nil);
player:endEvent();
end

View file

@ -1,7 +1,7 @@
require ("global") require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("Spl000");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_private_tristelle_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "processEventMERLIE", 1,1,1);
player:endEvent(); player:endEvent();
end end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_private_white_001", nil, nil, nil);
player:endEvent();
end

View file

@ -1,7 +1,7 @@
require ("global") require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultFst = GetStaticActor("DftFst"); defaultFst = GetStaticActor("Spl000");
callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithSerpent_sergeant_frilaix_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultFst, "processEventARISMONT", 1, 1, 1);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultSea = GetStaticActor("DftSea"); defaultSea = GetStaticActor("DftSea");
callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithMuscle-bounddeckhand_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithSailor031_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultSea = GetStaticActor("DftSea"); defaultSea = GetStaticActor("DftSea");
callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithPasty-facedadventurer_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithAdventurer030_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultSea = GetStaticActor("DftSea"); defaultSea = GetStaticActor("DftSea");
callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithPearly-toothedporter_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithPorter001_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultSea = GetStaticActor("DftSea"); defaultSea = GetStaticActor("DftSea");
callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithSkarnwaen_001", nil, nil, nil); callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithP_tahjha_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -1,7 +0,0 @@
require ("global")
function onEventStarted(player, npc)
defaultSea = GetStaticActor("DftSea");
callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithRubh_hob_001", nil, nil, nil);
player:endEvent();
end

View file

@ -2,6 +2,6 @@ require ("global")
function onEventStarted(player, npc) function onEventStarted(player, npc)
defaultSea = GetStaticActor("DftSea"); defaultSea = GetStaticActor("DftSea");
callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithSkarnwaen_001"); callClientFunction(player, "delegateEvent", player, defaultSea, "defaultTalkWithThosinbaen_001", nil, nil, nil);
player:endEvent(); player:endEvent();
end end

View file

@ -1,25 +1,25 @@
#!/bin/bash #!/bin/bash
IMPORT_PATH="C://coding//repositories//ffxiv related//ffxivclassic//ffxiv-classic-server//sql//" IMPORT_PATH="path/to/ffxiv-classic-server/sql/"
USER=root USER=root
PASS=root PASS=root
DBNAME=ffxiv_server DBNAME=ffxiv_server
ECHO Creating Database $DBNAME echo Creating Database $DBNAME
mysqladmin -h localhost -u $USER -p$PASS DROP $DBNAME mysql -h localhost -u $USER -p$PASS DROP $DBNAME
ECHO Creating Database $DBNAME echo Creating Database $DBNAME
mysqladmin -h localhost -u $USER -p$PASS CREATE $DBNAME IF NOT EXISTS $DBNAME mysql -h localhost -u $USER -p$PASS CREATE $DBNAME IF NOT EXISTS $DBNAME
ECHO Loading $DBNAME tables into the database echo Loading $DBNAME tables into the database
sh cd $IMPORT_PATH
for X in '*.sql'; for X in $IMPORT_PATH'*.sql';
do do
for Y in $X for Y in $X
do do
echo Importing $Y; echo Importing $Y;
"C:\program files\mysql\mysql server 5.7\bin\mysql" $DBNAME -h localhost -u $USER -p$PASS < $Y mysql $DBNAME -h localhost -u $USER -p$PASS < $Y
done done
done done
ECHO Finished! echo Finished!

25
sql/supportdesk_faqs.sql Normal file
View file

@ -0,0 +1,25 @@
/*
MySQL Data Transfer
Source Host: localhost
Source Database: ffxiv_server
Target Host: localhost
Target Database: ffxiv_server
Date: 8/20/2016 7:15:35 PM
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for supportdesk_faqs
-- ----------------------------
CREATE TABLE `supportdesk_faqs` (
`slot` tinyint(4) NOT NULL,
`languageCode` tinyint(4) NOT NULL,
`title` varchar(128) NOT NULL,
`body` text NOT NULL,
PRIMARY KEY (`slot`,`languageCode`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `supportdesk_faqs` VALUES ('0', '1', 'Welcome to FFXIV Classic', 'Welcome to the FFXIV 1.0 server emulator FFXIVClassic!\r\n\r\nThis is still currently a work in progress, and you may find bugs or issues as you play with this server. Keep in mind that this is not even remotely close to being finished, and that it is a work in progress.\r\n\r\nCheck out the blog at: \r\nhttp://ffxivclassic.fragmenterworks.com/ \r\nCheck out videos at: \r\nhttps://www.youtube.com/channel/UCr2703_er1Dj7Lx5pzpQpfg');

View file

@ -0,0 +1,26 @@
/*
MySQL Data Transfer
Source Host: localhost
Source Database: ffxiv_server
Target Host: localhost
Target Database: ffxiv_server
Date: 8/20/2016 7:15:41 PM
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for supportdesk_issues
-- ----------------------------
CREATE TABLE `supportdesk_issues` (
`slot` smallint(4) unsigned NOT NULL,
`title` varchar(50) NOT NULL,
PRIMARY KEY (`slot`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `supportdesk_issues` VALUES ('0', 'Report Harassment');
INSERT INTO `supportdesk_issues` VALUES ('1', 'Report Cheating');
INSERT INTO `supportdesk_issues` VALUES ('2', 'Report a Bug or Glitch');
INSERT INTO `supportdesk_issues` VALUES ('3', 'Leave Suggestion');

View file

@ -0,0 +1,26 @@
/*
MySQL Data Transfer
Source Host: localhost
Source Database: ffxiv_server
Target Host: localhost
Target Database: ffxiv_server
Date: 8/21/2016 6:17:47 PM
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for supportdesk_tickets
-- ----------------------------
CREATE TABLE `supportdesk_tickets` (
`id` int(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`title` varchar(128) NOT NULL,
`body` text NOT NULL,
`langCode` smallint(4) unsigned NOT NULL,
`isOpen` tinyint(1) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records
-- ----------------------------