Merge branch 'database_work' into scripting

# Conflicts:
#	FFXIVClassic Map Server/actors/chara/Character.cs
#	FFXIVClassic Map Server/actors/chara/npc/Npc.cs
#	FFXIVClassic Map Server/actors/chara/player/Player.cs
This commit is contained in:
Filip Maj 2016-01-17 11:53:52 -05:00
commit db62b05fdc
40 changed files with 1838 additions and 849 deletions

View File

@ -1,5 +1,4 @@
using FFXIVClassic_Lobby_Server.dataobjects;
using MySql.Data.MySqlClient;
using MySql.Data.MySqlClient;
using Dapper;
using Newtonsoft.Json;
using System;
@ -8,14 +7,21 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Map_Server.dataobjects.database;
using FFXIVClassic_Map_Server.dataobjects.chara.npc;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.utils;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Lobby_Server.dataobjects;
using FFXIVClassic_Map_Server;
using FFXIVClassic_Map_Server.common.EfficientHashTables;
namespace FFXIVClassic_Lobby_Server
{
class Database
{
public static uint getUserIdFromSession(String sessionId)
{
uint id = 0;
@ -66,76 +72,6 @@ namespace FFXIVClassic_Lobby_Server
}
}
public static DBCharacter getCharacter(uint charId)
{
using (var 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)))
{
DBCharacter chara = null;
try
{
conn.Open();
chara = conn.Query<DBCharacter>("SELECT * FROM characters WHERE id=@CharaId", new { CharaId = charId }).SingleOrDefault();
}
catch (MySqlException e)
{
}
finally
{
conn.Dispose();
}
return chara;
}
}
public static DBAppearance getAppearance(bool loadFromPlayerTable, uint charaId)
{
using (var 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)))
{
DBAppearance appearance = null;
try
{
conn.Open();
if (loadFromPlayerTable)
appearance = conn.Query<DBAppearance>("SELECT * FROM characters_appearance WHERE characterId=@CharaId", new { CharaId = charaId }).SingleOrDefault();
else
appearance = conn.Query<DBAppearance>("SELECT * FROM npc_appearance WHERE npcId=@CharaId", new { CharaId = charaId }).SingleOrDefault();
}
catch (MySqlException e)
{
}
finally
{
conn.Dispose();
}
return appearance;
}
}
public static DBStats getCharacterStats(uint charaId)
{
using (var 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)))
{
DBStats stats = null;
try
{
conn.Open();
stats = conn.Query<DBStats>("SELECT * FROM characters_stats WHERE characterId=@CharaId", new { CharaId = charaId }).SingleOrDefault();
}
catch (MySqlException e)
{
}
finally
{
conn.Dispose();
}
return stats;
}
}
public static List<Npc> getNpcList()
{
using (var 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)))
@ -158,5 +94,500 @@ namespace FFXIVClassic_Lobby_Server
}
}
public static void loadPlayerCharacter(Player player)
{
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();
//Load basic info
query = @"
SELECT
name,
positionX,
positionY,
positionZ,
rotation,
actorState,
currentZoneId,
currentClassJob,
gcCurrent,
gcLimsaRank,
gcGridaniaRank,
gcUldahRank,
currentTitle,
guardian,
birthDay,
birthMonth,
initialTown,
tribe,
currentParty,
restBonus,
achievementPoints
FROM characters WHERE id = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
player.displayNameId = 0xFFFFFFFF;
player.customDisplayName = reader.GetString(0);
player.oldPositionX = player.positionX = reader.GetFloat(1);
player.oldPositionY = player.positionY = reader.GetFloat(2);
player.oldPositionZ = player.positionZ = reader.GetFloat(3);
player.oldRotation = player.rotation = reader.GetFloat(4);
player.currentMainState = reader.GetUInt16(5);
player.zoneId = reader.GetUInt32(6);
player.charaWork.parameterSave.state_mainSkill[0] = reader.GetByte(7);
player.gcCurrent = reader.GetByte(8);
player.gcRankLimsa = reader.GetByte(9);
player.gcRankGridania = reader.GetByte(10);
player.gcRankUldah = reader.GetByte(11);
player.currentTitle = reader.GetUInt32(12);
player.playerWork.guardian = reader.GetByte(13);
player.playerWork.birthdayDay = reader.GetByte(14);
player.playerWork.birthdayMonth = reader.GetByte(15);
player.playerWork.initialTown = reader.GetByte(16);
player.playerWork.tribe = reader.GetByte(17);
player.playerWork.restBonusExpRate = reader.GetInt32(19);
player.achievementPoints = reader.GetUInt32(20);
}
}
player.charaWork.parameterSave.state_mainSkillLevel = 49;
/*
//Get level of our classjob
//Load appearance
query = @"
SELECT
baseId
FROM characters_appearance WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
}
}
*/
//Get level of our classjob
//Load appearance
query = @"
SELECT
hp,
hpMax,
mp,
mpMax
FROM characters_parametersave WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
player.charaWork.parameterSave.hp[0] = reader.GetInt16(0);
player.charaWork.parameterSave.hpMax[0] = reader.GetInt16(1);
player.charaWork.parameterSave.mp = reader.GetInt16(2);
player.charaWork.parameterSave.mpMax = reader.GetInt16(3);
}
}
//Load appearance
query = @"
SELECT
baseId,
size,
voice,
skinColor,
hairStyle,
hairColor,
hairHighlightColor,
eyeColor,
characteristics,
characteristicsColor,
faceType,
ears,
faceMouth,
faceFeatures,
faceNose,
faceEyeShape,
faceIrisSize,
faceEyebrows,
mainHand,
offHand,
head,
body,
hands,
legs,
feet,
waist,
leftFinger,
rightFinger,
leftEars,
rightEars
FROM characters_appearance WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
if (reader.GetUInt32(0) == 0xFFFFFFFF)
player.modelId = CharacterUtils.getTribeModel(player.playerWork.tribe);
else
player.modelId = reader.GetUInt32(0);
player.appearanceIds[Character.SIZE] = reader.GetByte(1);
player.appearanceIds[Character.COLORINFO] = (uint)(reader.GetUInt16(3) | (reader.GetUInt16(5) << 10) | (reader.GetUInt16(7) << 20));
player.appearanceIds[Character.FACEINFO] = PrimitiveConversion.ToUInt32(CharacterUtils.getFaceInfo(reader.GetByte(8), reader.GetByte(9), reader.GetByte(10), reader.GetByte(11), reader.GetByte(12), reader.GetByte(13), reader.GetByte(14), reader.GetByte(15), reader.GetByte(16), reader.GetByte(17)));
player.appearanceIds[Character.HIGHLIGHT_HAIR] = (uint)(reader.GetUInt16(6) | reader.GetUInt16(4) << 10);
player.appearanceIds[Character.VOICE] = reader.GetByte(2);
player.appearanceIds[Character.WEAPON1] = reader.GetUInt32(18);
player.appearanceIds[Character.WEAPON2] = reader.GetUInt32(19);
player.appearanceIds[Character.HEADGEAR] = reader.GetUInt32(20);
player.appearanceIds[Character.BODYGEAR] = reader.GetUInt32(21);
player.appearanceIds[Character.LEGSGEAR] = reader.GetUInt32(22);
player.appearanceIds[Character.HANDSGEAR] = reader.GetUInt32(23);
player.appearanceIds[Character.FEETGEAR] = reader.GetUInt32(24);
player.appearanceIds[Character.WAISTGEAR] = reader.GetUInt32(25);
player.appearanceIds[Character.R_EAR] = reader.GetUInt32(26);
player.appearanceIds[Character.L_EAR] = reader.GetUInt32(27);
player.appearanceIds[Character.R_FINGER] = reader.GetUInt32(28);
player.appearanceIds[Character.L_FINGER] = reader.GetUInt32(29);
}
}
//Load Status Effects
query = @"
SELECT
statusId,
expireTime
FROM characters_statuseffect WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
int count = 0;
while (reader.Read())
{
player.charaWork.status[count] = reader.GetUInt16(0);
player.charaWork.statusShownTime[count] = reader.GetUInt32(1);
}
}
//Load Chocobo
query = @"
SELECT
hasChocobo,
hasGoobbue,
chocoboAppearance,
chocoboName
FROM characters_chocobo WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
player.hasChocobo = reader.GetBoolean(0);
player.hasGoobbue = reader.GetBoolean(1);
player.chocoboAppearance = reader.GetByte(2);
player.chocoboName = reader.GetString(3);
}
}
//Load Timers
query = @"
SELECT
thousandmaws,
dzemaeldarkhold,
bowlofembers_hard,
bowlofembers,
thornmarch,
aurumvale,
cutterscry,
battle_aleport,
battle_hyrstmill,
battle_goldenbazaar,
howlingeye_hard,
howlingeye,
castrumnovum,
bowlofembers_extreme,
rivenroad,
rivenroad_hard,
behests,
companybehests,
returntimer,
skirmish
FROM characters_timers WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
for (int i = 0; i < player.timers.Length; i++)
player.timers[i] = reader.GetUInt32(i);
}
}
//Load Hotbar
query = @"
SELECT
hotbarSlot,
commandId,
recastTime
FROM characters_hotbar WHERE characterId = @charId AND classId = @classId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@classId", player.charaWork.parameterSave.state_mainSkill[0]);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int index = reader.GetUInt16(0);
player.charaWork.command[index+32] = reader.GetUInt32(1);
player.charaWork.parameterSave.commandSlot_recastTime[index] = reader.GetUInt32(2);
}
}
//Load Scenario Quests
query = @"
SELECT
slot,
questId
FROM characters_quest_scenario WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int index = reader.GetUInt16(0);
player.playerWork.questScenario[index] = 0xA0F00000 | reader.GetUInt32(1);
}
}
//Load Local Guildleves
query = @"
SELECT
slot,
questId,
abandoned,
completed
FROM characters_quest_guildleve_local WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int index = reader.GetUInt16(0);
player.playerWork.questGuildleve[index] = 0xA0F00000 | reader.GetUInt32(1);
}
}
//Load Regional Guildleve Quests
query = @"
SELECT
slot,
guildleveId,
abandoned,
completed
FROM characters_quest_guildleve_regional WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int index = reader.GetUInt16(0);
player.work.guildleveId[index] = reader.GetUInt16(1);
player.work.guildleveDone[index] = reader.GetBoolean(2);
player.work.guildleveChecked[index] = reader.GetBoolean(3);
}
}
//Load NPC Linkshell
query = @"
SELECT
npcLinkshellId,
isCalling,
isExtra
FROM characters_npclinkshell WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int npcLSId = reader.GetUInt16(0);
player.playerWork.npcLinkshellChatCalling[npcLSId] = reader.GetBoolean(1);
player.playerWork.npcLinkshellChatExtra[npcLSId] = reader.GetBoolean(2);
}
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
}
public static SubPacket getLatestAchievements(Player player)
{
uint[] latestAchievements = new uint[5];
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();
//Load Last 5 Completed
string query = @"
SELECT
characters_achievements.achievementId FROM characters_achievements
INNER JOIN gamedata_achievements ON characters_achievements.achievementId = gamedata_achievements.achievementId
WHERE characterId = @charId AND rewardPoints <> 0 ORDER BY timeDone LIMIT 5";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
int count = 0;
while (reader.Read())
{
uint id = reader.GetUInt32(0);
latestAchievements[count++] = id;
}
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
return SetLatestAchievementsPacket.buildPacket(player.actorId, latestAchievements);
}
public static SubPacket getAchievementsPacket(Player player)
{
SetCompletedAchievementsPacket cheevosPacket = new SetCompletedAchievementsPacket();
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 packetOffsetId
FROM characters_achievements
INNER JOIN gamedata_achievements ON characters_achievements.achievementId = gamedata_achievements.achievementId
WHERE characterId = @charId AND timeDone IS NOT NULL";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
uint offset = reader.GetUInt32(0);
if (offset < 0 || offset >= cheevosPacket.achievementFlags.Length)
{
Log.error("SQL Error; achievement flag offset id out of range: " + offset);
continue;
}
cheevosPacket.achievementFlags[offset] = true;
}
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
return cheevosPacket.buildPacket(player.actorId);
}
public static void loadZones(Efficient32bitHashTable<Zone> zoneList)
{
int count = 0;
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
id,
regionId,
zoneName,
dayMusic,
nightMusic,
battleMusic,
isInn,
canRideChocobo,
canStealth,
isInstanceRaid
FROM server_zones
WHERE zoneName IS NOT NULL";
MySqlCommand cmd = new MySqlCommand(query, conn);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read()) {
Zone zone = new Zone(reader.GetUInt32(0), reader.GetString(2), reader.GetUInt16(1), reader.GetUInt16(3), reader.GetUInt16(4), reader.GetUInt16(5), reader.GetBoolean(6), reader.GetBoolean(7), reader.GetBoolean(8), reader.GetBoolean(9));
zoneList.Add(zone.actorId, zone);
count++;
}
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
Log.info(String.Format("Loaded {0} zones.", count));
}
}
}

View File

@ -64,11 +64,18 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="actors\chara\npc\NpcWork.cs" />
<Compile Include="actors\chara\AetheryteWork.cs" />
<Compile Include="actors\chara\Work.cs" />
<Compile Include="actors\debug\Debug.cs" />
<Compile Include="actors\director\WeatherDirector.cs" />
<Compile Include="actors\judge\Judge.cs" />
<Compile Include="actors\StaticActors.cs" />
<Compile Include="actors\world\WorldMaster.cs" />
<Compile Include="ClientConnection.cs" />
<Compile Include="common\Bitfield.cs" />
<Compile Include="common\Blowfish.cs" />
<Compile Include="common\EfficientHashTables.cs" />
<Compile Include="common\Log.cs" />
<Compile Include="common\STA_INIFile.cs" />
<Compile Include="common\Utils.cs" />
@ -84,17 +91,10 @@
<Compile Include="actors\chara\ParameterTemp.cs" />
<Compile Include="actors\chara\player\Player.cs" />
<Compile Include="actors\command\Command.cs" />
<Compile Include="dataobjects\CharaInfo.cs" />
<Compile Include="actors\chara\CharaWork.cs" />
<Compile Include="actors\chara\ParameterSave.cs" />
<Compile Include="actors\chara\player\PlayerWork.cs" />
<Compile Include="dataobjects\database\DBAppearance.cs" />
<Compile Include="dataobjects\database\DBCharacter.cs" />
<Compile Include="dataobjects\database\DBCommands.cs" />
<Compile Include="dataobjects\database\DBJournal.cs" />
<Compile Include="dataobjects\database\DBPlayerData.cs" />
<Compile Include="dataobjects\database\DBStats.cs" />
<Compile Include="dataobjects\database\DBWorld.cs" />
<Compile Include="dataobjects\DBWorld.cs" />
<Compile Include="dataobjects\Item.cs" />
<Compile Include="dataobjects\ConnectedPlayer.cs" />
<Compile Include="dataobjects\RecruitmentDetails.cs" />
@ -209,16 +209,16 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="lua\LuaUtils.cs" />
<Compile Include="Server.cs" />
<Compile Include="Zone.cs" />
<Compile Include="utils\ActorPropertyPacketUtil.cs" />
<Compile Include="utils\CharacterUtils.cs" />
<Compile Include="utils\SQLGeneration.cs" />
<Compile Include="actors\area\Zone.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="actors\area\" />
<Folder Include="actors\director\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>

View File

@ -33,6 +33,10 @@ using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.dataobjects.actors;
using FFXIVClassic_Map_Server.dataobjects.chara.npc;
using FFXIVClassic_Map_Server.actors;
using System.Net;
using FFXIVClassic_Map_Server.actors.debug;
using FFXIVClassic_Map_Server.actors.world;
using FFXIVClassic_Map_Server.common.EfficientHashTables;
namespace FFXIVClassic_Lobby_Server
{
@ -43,13 +47,18 @@ namespace FFXIVClassic_Lobby_Server
List<ClientConnection> mConnections;
StaticActors mStaticActors = new StaticActors();
Zone inn = new Zone();
DebugProg debug = new DebugProg();
WorldMaster worldMaster = new WorldMaster();
Efficient32bitHashTable<Zone> zoneList = new Efficient32bitHashTable<Zone>();
public PacketProcessor(Dictionary<uint, ConnectedPlayer> playerList, List<ClientConnection> connectionList)
{
mPlayers = playerList;
mConnections = connectionList;
initNpcs();
Database.loadZones(zoneList);
}
public void processPacket(ClientConnection client, BasePacket packet)
@ -123,11 +132,7 @@ namespace FFXIVClassic_Lobby_Server
if (actorID == 0)
break;
//Second connection
if (mPlayers.ContainsKey(actorID))
player = mPlayers[actorID];
using (MemoryStream mem = new MemoryStream(reply2.data))
{
using (BinaryWriter binReader = new BinaryWriter(mem))
@ -137,7 +142,7 @@ namespace FFXIVClassic_Lobby_Server
}
}
if (player == null)
if (((IPEndPoint)client.socket.LocalEndPoint).Port == 54992)
{
player = new ConnectedPlayer(actorID);
mPlayers[actorID] = player;
@ -184,30 +189,21 @@ namespace FFXIVClassic_Lobby_Server
client.queuePacket(BasePacket.createPacket(PongPacket.buildPacket(player.actorID, pingPacket.time), true, false));
break;
//Unknown
case 0x0002:
BasePacket packet196 = new BasePacket("./packets/196");
case 0x0002:
BasePacket reply7 = new BasePacket("./packets/login/login7_data.bin");
BasePacket reply8 = new BasePacket("./packets/login/login8_data.bin");
BasePacket reply9 = new BasePacket("./packets/login/login9_zonesetup.bin");
BasePacket reply10 = new BasePacket("./packets/login/login10.bin");
BasePacket reply11 = new BasePacket("./packets/login/login11.bin");
BasePacket reply12 = new BasePacket("./packets/login/login12.bin");
player.getActor().zone = zoneList.Get(player.getActor().zoneId);
// BasePacket keyitems = new BasePacket("./packets/login/keyitems.bin");
// BasePacket currancy = new BasePacket("./packets/login/currancy.bin");
BasePacket reply9 = new BasePacket("./packets/login/login9_zonesetup.bin"); //Bed, Book created
BasePacket reply10 = new BasePacket("./packets/login/login10.bin"); //Item Storage, Inn Door created
BasePacket reply11 = new BasePacket("./packets/login/login11.bin"); //NPC Create ??? Final init
#region replaceid
//currancy.replaceActorID(player.actorID);
//keyitems.replaceActorID(player.actorID);
packet196.replaceActorID(player.actorID);
reply7.replaceActorID(player.actorID);
reply8.replaceActorID(player.actorID);
reply9.replaceActorID(player.actorID);
reply10.replaceActorID(player.actorID);
reply11.replaceActorID(player.actorID);
reply12.replaceActorID(player.actorID);
#endregion
client.queuePacket(SetMapPacket.buildPacket(player.actorID, 0xD1, 0xF4), true, false);
@ -217,7 +213,7 @@ namespace FFXIVClassic_Lobby_Server
client.queuePacket(SetMusicPacket.buildPacket(player.actorID, 0x3D, 0x01), true, false);
client.queuePacket(SetWeatherPacket.buildPacket(player.actorID, SetWeatherPacket.WEATHER_CLEAR), true, false);
BasePacket actorPacket = player.getActor().getInitPackets(player.actorID);
BasePacket actorPacket = player.getActor().getSpawnPackets(player.actorID);
client.queuePacket(actorPacket);
//Retainers
@ -236,10 +232,10 @@ namespace FFXIVClassic_Lobby_Server
BasePacket partyListPacket = BasePacket.createPacket(ListUtils.createPartyList(player.actorID, 0xF4, 1, 0x8000000000696df2, partyListEntries), true, false);
client.queuePacket(partyListPacket);
#region itemsetup
////////ITEMS////////
client.queuePacket(InventoryBeginChangePacket.buildPacket(player.actorID), true, false);
#region itemsetup
//TEST
List<Item> items = new List<Item>();
@ -276,14 +272,14 @@ namespace FFXIVClassic_Lobby_Server
setinvPackets.Add(beginInventory);
setinvPackets.Add(setInventory);
setinvPackets.Add(endInventory);
#endregion
client.queuePacket(BasePacket.createPacket(setinvPackets, true, false));
//client.queuePacket(currancy);
//client.queuePacket(keyitems);
#endregion
#region equipsetup
client.queuePacket(BasePacket.createPacket(setinvPackets, true, false));
EquipmentSetupPacket initialEqupmentPacket = new EquipmentSetupPacket();
initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_BODY, 5);
initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_HEAD, 3);
@ -291,7 +287,6 @@ namespace FFXIVClassic_Lobby_Server
initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_UNDERGARMENT, 7);
initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_MAINHAND, 2);
initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_LEGS, 8);
#endregion
//Equip Init
client.queuePacket(InventorySetBeginPacket.buildPacket(player.actorID, 0x23, InventorySetBeginPacket.CODE_EQUIPMENT), true, false);
@ -299,59 +294,28 @@ namespace FFXIVClassic_Lobby_Server
client.queuePacket(InventorySetEndPacket.buildPacket(player.actorID), true, false);
client.queuePacket(InventoryEndChangePacket.buildPacket(player.actorID), true, false);
////////ITEMS////////
////////ITEMS////////
client.queuePacket(SetGrandCompanyPacket.buildPacket(player.actorID, player.actorID, 0x01, 0x1B, 0x1B, 0x1B), true, false);
client.queuePacket(SetPlayerTitlePacket.buildPacket(player.actorID, player.actorID, 0x00), true, false);
client.queuePacket(SetCurrentJobPacket.buildPacket(player.actorID, player.actorID, 0x13), true, false);
//client.queuePacket(packet196);//client.queuePacket(_0x196Packet.buildPacket(player.actorID, player.actorID), true, false);
client.queuePacket(SetChocoboNamePacket.buildPacket(player.actorID, player.actorID, "Boco"), true, false);
client.queuePacket(SetHasChocoboPacket.buildPacket(player.actorID, true), true, false);
client.queuePacket(SetHasGoobbuePacket.buildPacket(player.actorID, true), true, false);
#endregion
SetCompletedAchievementsPacket cheevos = new SetCompletedAchievementsPacket();
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_BATTLE] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_CHARACTER] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_CURRENCY] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_DUNGEONS] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_EXPLORATION] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_GATHERING] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_GRAND_COMPANY] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_ITEMS] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_MATERIA] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_QUESTS] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_SEASONAL_EVENTS] = true;
cheevos.achievementFlags[SetCompletedAchievementsPacket.CATEGORY_SYNTHESIS] = true;
client.queuePacket(cheevos.buildPacket(player.actorID), true, false);
BasePacket tpacket = player.getActor().getInitPackets(player.actorID);
//tpacket.debugPrintPacket();
client.queuePacket(tpacket);
client.queuePacket(SetLatestAchievementsPacket.buildPacket(player.actorID, new uint[5]), true, false);
client.queuePacket(SetAchievementPointsPacket.buildPacket(player.actorID, 0x00), true, false);
player.getActor().zone.addActorToZone(player.getActor());
SetCutsceneBookPacket book = new SetCutsceneBookPacket();
for (int i = 0; i < book.cutsceneFlags.Length; i++)
book.cutsceneFlags[i] = true;
client.queuePacket(book.buildPacket(player.actorID), true, false);
BasePacket innSpawn = player.getActor().zone.getSpawnPackets(player.actorID);
BasePacket debugSpawn = debug.getSpawnPackets(player.actorID);
BasePacket worldMasterSpawn = worldMaster.getSpawnPackets(player.actorID);
innSpawn.debugPrintPacket();
//client.queuePacket(SetPlayerDreamPacket.buildPacket(player.actorID, 11), true, false);
//BasePacket packet1a5 = new BasePacket("./packets/1ax/1a5");
//packet1a5.replaceActorID(player.actorID);
//client.queuePacket(packet1a5);
client.queuePacket(innSpawn);
client.queuePacket(debugSpawn);
client.queuePacket(worldMasterSpawn);
//loadTest(client, player);
//return;
inn.addActorToZone(player.getActor());
// BasePacket tpacket = BasePacket.createPacket(player.getActor().createInitSubpackets(player.actorID), true, false);
// client.queuePacket(tpacket);
client.queuePacket(reply7);
client.queuePacket(reply8);
client.queuePacket(reply9);
client.queuePacket(reply10);
// client.queuePacket(reply11);
client.queuePacket(reply12);
client.queuePacket(reply11);
break;
//Chat Received
@ -368,9 +332,9 @@ namespace FFXIVClassic_Lobby_Server
//Update Position
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
player.updatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
//Update Instance
List<BasePacket> instanceUpdatePackets = player.updateInstance(inn.getActorsAroundActor(player.getActor(), 50));
List<BasePacket> instanceUpdatePackets = player.updateInstance(player.getActor().zone.getActorsAroundActor(player.getActor(), 50));
foreach (BasePacket bp in instanceUpdatePackets)
client.queuePacket(bp);
@ -559,10 +523,12 @@ namespace FFXIVClassic_Lobby_Server
*/
private void initNpcs()
{
/*
List<Npc> npcList = Database.getNpcList();
foreach (Npc npc in npcList)
inn.addActorToZone(npc);
Log.info(String.Format("Loaded {0} npcs...", npcList.Count));
* */
}
private void loadTest(ClientConnection client, ConnectedPlayer player)
@ -601,8 +567,8 @@ namespace FFXIVClassic_Lobby_Server
packet.replaceActorID(entry.Value.actorID);
actorPacket.replaceActorID(entry.Value.actorID);
entry.Value.getConnection2().queuePacket(packet);
entry.Value.getConnection2().queuePacket(actorPacket);
entry.Value.getConnection1().queuePacket(packet);
entry.Value.getConnection1().queuePacket(actorPacket);
}

View File

@ -6,8 +6,8 @@ using FFXIVClassic_Lobby_Server.common;
using System.Runtime.InteropServices;
using MySql.Data.MySqlClient;
using System.Reflection;
using FFXIVClassic_Lobby_Server.dataobjects;
using System.IO;
using FFXIVClassic_Lobby_Server.dataobjects;
namespace FFXIVClassic_Lobby_Server
{
@ -16,7 +16,6 @@ namespace FFXIVClassic_Lobby_Server
static void Main(string[] args)
{
#if DEBUG
TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out);
Debug.Listeners.Add(myWriter);

View File

@ -226,13 +226,16 @@ namespace FFXIVClassic_Lobby_Server
public void testCodePacket(uint id, uint value, string target)
{
SetActorPropetyPacket changeProperty = new SetActorPropetyPacket();
changeProperty.addInt(id, value);
SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(target);
changeProperty.setTarget(target);
changeProperty.addInt(id, value);
changeProperty.addTarget();
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
SubPacket changePropertyPacket = changeProperty.buildPacket((entry.Value.actorID), (entry.Value.actorID));
BasePacket packet = BasePacket.createPacket(changePropertyPacket, true, false);
packet.debugPrintPacket();
if (entry.Value.getConnection1() != null)
@ -250,7 +253,7 @@ namespace FFXIVClassic_Lobby_Server
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
SetActorPropetyPacket changeProperty = new SetActorPropetyPacket();
SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(target);
changeProperty.addProperty(entry.Value.getActor(), name);
changeProperty.addProperty(entry.Value.getActor(), "charaWork.parameterSave.hpMax[0]");
changeProperty.setTarget(target);

View File

@ -1,11 +1,9 @@
using FFXIVClassic_Lobby_Server;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.dataobjects;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.Actor;
using System;
using System.Collections;
using System.Collections.Generic;
@ -24,14 +22,14 @@ namespace FFXIVClassic_Map_Server.dataobjects
public uint displayNameId = 0xFFFFFFFF;
public string customDisplayName;
public uint currentMainState = SetActorStatePacket.MAIN_STATE_PASSIVE;
public uint currentSubState = SetActorStatePacket.SUB_STATE_NONE;
public float positionX = SetActorPositionPacket.INNPOS_X, positionY = SetActorPositionPacket.INNPOS_Y, positionZ = SetActorPositionPacket.INNPOS_Z, rotation = SetActorPositionPacket.INNPOS_ROT;
public ushort currentMainState = SetActorStatePacket.MAIN_STATE_PASSIVE;
public ushort currentSubState = SetActorStatePacket.SUB_STATE_NONE;
public float positionX, positionY, positionZ, rotation;
public float oldPositionX, oldPositionY, oldPositionZ, oldRotation;
public ushort moveState, oldMoveState;
public uint currentZoneId;
public uint zoneId;
public Zone zone = null;
public bool isZoning = false;
public bool spawnedFirstTime = false;
@ -102,7 +100,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, classParams);
}
public virtual BasePacket getInitPackets(uint playerActorId)
public virtual BasePacket getSpawnPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(createAddActorPacket(playerActorId));
@ -114,7 +112,14 @@ namespace FFXIVClassic_Map_Server.dataobjects
subpackets.Add(createScriptBindPacket(playerActorId));
return BasePacket.createPacket(subpackets, true, false);
}
public virtual BasePacket getInitPackets(uint playerActorId)
{
SetActorPropetyPacket initProperties = new SetActorPropetyPacket("/_init");
initProperties.addTarget();
return BasePacket.createPacket(initProperties.buildPacket(playerActorId, actorId), true, false);
}
public override bool Equals(Object obj)
{
Actor actorObj = obj as Actor;

View File

@ -1,5 +1,8 @@
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
using System.Linq;
@ -8,19 +11,41 @@ using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server
{
class Zone
class Zone : Actor
{
public uint mapId;
public string zoneName;
public ushort regionId;
public bool canStealth, isInn, canRideChocobo, isInstanceRaid;
public ushort weatherNormal, weatherCommon, weatherRare;
public ushort bgmDay, bgmNight, bgmBattle;
public int boundingGridSize = 50;
public int minX = -100, minY = -100, maxX = 100, maxY = 100;
private int numXBlocks, numYBlocks;
private int halfWidth, halfHeight;
private List<Actor>[,] actorBlock;
public Zone()
public Zone(uint id, string zoneName, ushort regionId, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool canStealth, bool isInn, bool canRideChocobo, bool isInstanceRaid)
: base(id)
{
this.zoneName = zoneName;
this.regionId = regionId;
this.canStealth = canStealth;
this.isInn = isInn;
this.canRideChocobo = canRideChocobo;
this.isInstanceRaid = isInstanceRaid;
this.bgmDay = bgmDay;
this.bgmNight = bgmNight;
this.bgmBattle = bgmBattle;
this.displayNameId = 0;
this.customDisplayName = "_areaMaster";
this.actorName = String.Format("_areaMaster@{0:X5}",id<<8);
this.className = "ZoneMasterPrvI0";
numXBlocks = (maxX - minX) / boundingGridSize;
numYBlocks = (maxY - minY) / boundingGridSize;
actorBlock = new List<Actor>[numXBlocks, numYBlocks];
@ -37,6 +62,26 @@ namespace FFXIVClassic_Map_Server
}
public override SubPacket createScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.createLuaParamList("/Area/Zone/ZoneMasterPrvI0", false, true, zoneName, "", 0xFFFFFFFF, false, false, canStealth, isInn, false, false, false, false, false, false);
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams);
}
public override BasePacket getSpawnPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(createAddActorPacket(playerActorId));
subpackets.Add(createSpeedPacket(playerActorId));
subpackets.Add(createSpawnPositonPacket(playerActorId, 0x1));
subpackets.Add(createNamePacket(playerActorId));
subpackets.Add(createStatePacket(playerActorId));
subpackets.Add(createIsZoneingPacket(playerActorId));
subpackets.Add(createScriptBindPacket(playerActorId));
return BasePacket.createPacket(subpackets, true, false);
}
#region Actor Management
public void addActorToZone(Actor actor)

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.dataobjects.chara
{
class AetheryteWork
{
public int iconGil;
public short guildleveId;
public short clearTime;
public int missionBonus;
public int difficultyBonus;
public byte factionNumber;
public int factionBonus;
public byte factionCredit;
public int glRewardItem;
public int glRewardNumber;
public int glRewardSubItem;
public int glRewardSubNumber;
public byte difficulty;
}
}

View File

@ -8,11 +8,12 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
{
class BattleSave
{
public float potencial;
public int skillLevel;
public int skillLevelCap;
public int[] skillPoint;
public float potencial = 6.6f;
public short[] skillLevel = new short[52];
public short[] skillLevelCap = new short[52];
public short[] skillPoint = new short[52];
public short physicalLevel;
public int physicalExp;
public bool[] negotiationFlag= new bool[2];

View File

@ -8,27 +8,29 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
{
class BattleTemp
{
public const uint NAMEPLATE_SHOWN = 0xFBFBCFB1;
public const uint TARGETABLE = 0x2138FD71;
public const uint NAMEPLATE_SHOWN = 0;
public const uint TARGETABLE = 1;
//public const uint NAMEPLATE_SHOWN2 = 2;
public const uint NAMEPLATE_SHOWN2 = 3;
public const uint STAT_STRENGTH = 4;
public const uint STAT_VITALITY = 5;
public const uint STAT_DEXTERITY = 6;
public const uint STAT_INTELLIGENCE = 7;
public const uint STAT_MIND = 8;
public const uint STAT_PIETY = 9;
public const uint STAT_STRENGTH = 3;
public const uint STAT_VITALITY = 4;
public const uint STAT_DEXTERITY = 5;
public const uint STAT_INTELLIGENCE = 6;
public const uint STAT_MIND = 7;
public const uint STAT_PIETY = 8;
public const uint STAT_RESISTANCE_FIRE = 10;
public const uint STAT_RESISTANCE_ICE = 11;
public const uint STAT_RESISTANCE_WIND = 12;
public const uint STAT_RESISTANCE_LIGHTNING = 3;
public const uint STAT_RESISTANCE_EARTH = 14;
public const uint STAT_RESISTANCE_WATER = 15;
public const uint STAT_RESISTANCE_FIRE = 9;
public const uint STAT_RESISTANCE_ICE = 10;
public const uint STAT_RESISTANCE_WIND = 11;
public const uint STAT_RESISTANCE_LIGHTNING = 12;
public const uint STAT_RESISTANCE_EARTH = 13;
public const uint STAT_RESISTANCE_WATER = 14;
public const uint STAT_ATTACK = 18;
public const uint STAT_ACCURACY = 16;
public const uint STAT_NORMALDEFENSE = 19;
public const uint STAT_EVASION = 17;
public const uint STAT_ATTACK = 17;
public const uint STAT_ACCURACY = 15;
public const uint STAT_NORMALDEFENSE = 18;
public const uint STAT_EVASION = 16;
public const uint STAT_ATTACK_MAGIC = 24;
public const uint STAT_HEAL_MAGIC = 25;
public const uint STAT_ENCHANCEMENT_MAGIC_POTENCY = 26;
@ -45,8 +47,8 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
public const uint STAT_HARVEST_LIMIT = 34;
public const uint STAT_HARVEST_RATE = 35;
public int[] castGauge_speed = new int[2];
public float[] castGauge_speed = { 1.0f, 0.25f};
public bool[] timingCommandFlag = new bool[4];
public ushort[] generalParameter = new ushort[32];
public ushort[] generalParameter = new ushort[35];
}
}

View File

@ -18,17 +18,21 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
public EventSave eventSave = new EventSave();
public EventTemp eventTemp = new EventTemp();
public bool gameParameter = false;
public byte[] property = new byte[32];
public ushort[] status = new ushort[20];
public uint[] statusShownTime = new uint[20];
public int[] command = new int[64];
public int[] commandCategory = new int[64];
public int commandBorder = 0x20;
public bool commandAcquired = false;
public bool[] additionalCommandAcquired = new bool[1];
public uint[] command = new uint[64]; //ACTORS
public byte[] commandCategory = new byte[64];
public byte commandBorder = 0x20;
public bool[] commandAcquired = new bool[4096];
public bool[] additionalCommandAcquired = new bool[36];
public uint currentContentGroup;
public uint depictionJudge = 0xa0f50911;
}
}

View File

@ -1,4 +1,5 @@
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.actors.chara;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
@ -45,12 +46,15 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
public uint currentLockedTarget = 0xC0000000;
public uint currentActorIcon = 0;
public CharaWork charaWork = new CharaWork();
public PlayerWork playerWork = new PlayerWork();
public Character(uint actorId) : base(actorId)
{
public Work work = new Work();
public CharaWork charaWork = new CharaWork();
public Character(uint actorID) : base(actorID)
{
//Init timer array to "notimer"
for (int i = 0; i < charaWork.statusShownTime.Length; i++)
charaWork.statusShownTime[i] = 0xFFFFFFFF;
}
public SubPacket createAppearancePacket(uint playerActorId)

View File

@ -9,7 +9,7 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
class EventSave
{
public bool bazaar;
public float bazaarTax;
public int repairType;
public byte bazaarTax;
public byte repairType;
}
}

View File

@ -8,19 +8,30 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
{
class ParameterSave
{
public int[] hp = new int[1];
public int[] hpMax = new int[1];
public int mp;
public int mpMax;
public short[] hp = new short[8];
public short[] hpMax = new short[8];
public short mp;
public short mpMax;
public int[] state_mainSkill = new int[4];
public int state_mainSkillLevel;
public byte[] state_mainSkill = new byte[4];
public ushort state_mainSkillLevel;
public int[] state_boostPointForSkill;
public byte[] state_boostPointForSkill = new byte[4];
public uint[] commandSlot_recastTime = new uint[40];
public bool[] commandSlot_compatibility = new bool[40];
public int[] commandSlot_compatibility;
public int[] commandSlot_recastTime;
public ushort[] giftCommandSlot_commandId = new ushort[10];
public int[] giftCommandSlot_commandId;
public ushort[] constanceCommandSlot_commandId = new ushort[10];
public byte abilityCostPoint_used;
public byte abilityCostPoint_max;
public byte giftCostPoint_used;
public byte giftCostPoint_max;
public byte constanceCostPoint_used;
public byte constanceCostPoint_max;
}
}

View File

@ -8,16 +8,16 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
{
class ParameterTemp
{
public int tp = 0;
public short tp = 0;
public int targetInformation = 0;
public int[] maxCommandRecastTime = new int[40];
public ushort[] maxCommandRecastTime = new ushort[40];
public float[] forceControl_float_forClientSelf = new float[4];
public short[] forceControl_int16_forClientSelf = new short[2];
public float[] forceControl_float_forClientSelf = { 1.0f, 1.0f, 0.0f, 0.0f};
public short[] forceControl_int16_forClientSelf = { -1, -1 };
public int[] otherClassAbilityCount = new int[2];
public int[] giftCount = new int[2];
public byte[] otherClassAbilityCount = new byte[2];
public byte[] giftCount = new byte[2];
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara
{
class Work
{
public ushort[] guildleveId = new ushort[16];
public bool[] guildleveDone = new bool[16];
public bool[] guildleveChecked = new bool[16];
public bool betacheck = false;
public bool[] event_achieve_aetheryte = new bool[512];
}
}

View File

@ -1,6 +1,5 @@
using FFXIVClassic_Lobby_Server;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.dataobjects;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
@ -30,35 +29,6 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara.npc
if (initParams.Length != 0)
this.classParams = LuaUtils.readLuaParams(initParams);
setPlayerAppearance();
}
public void setPlayerAppearance()
{
DBAppearance appearance = Database.getAppearance(false, actorId);
if (appearance == null)
return;
modelId = DBAppearance.getTribeModel(appearance.tribe);
appearanceIds[SIZE] = appearance.size;
appearanceIds[COLORINFO] = (uint)(appearance.skinColor | (appearance.hairColor << 10) | (appearance.eyeColor << 20));
appearanceIds[FACEINFO] = PrimitiveConversion.ToUInt32(appearance.getFaceInfo());
appearanceIds[HIGHLIGHT_HAIR] = (uint)(appearance.hairHighlightColor | appearance.hairStyle << 10);
appearanceIds[VOICE] = appearance.voice;
appearanceIds[WEAPON1] = appearance.mainHand;
appearanceIds[WEAPON2] = appearance.offHand;
appearanceIds[HEADGEAR] = appearance.head;
appearanceIds[BODYGEAR] = appearance.body;
appearanceIds[LEGSGEAR] = appearance.legs;
appearanceIds[HANDSGEAR] = appearance.hands;
appearanceIds[FEETGEAR] = appearance.feet;
appearanceIds[WAISTGEAR] = appearance.waist;
appearanceIds[R_EAR] = appearance.rightEar;
appearanceIds[L_EAR] = appearance.leftEar;
appearanceIds[R_FINGER] = appearance.rightFinger;
appearanceIds[L_FINGER] = appearance.leftFinger;
}
public override BasePacket getInitPackets(uint playerActorId)

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.dataobjects.chara
{
class NpcWork
{
public short pushCommand;
public int pushCommandSub;
public byte pushCommandPriority;
public byte hateType;
}
}

View File

@ -1,10 +1,11 @@
using FFXIVClassic_Lobby_Server;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.dataobjects;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects.database;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Map_Server.utils;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
@ -39,7 +40,23 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
public uint[] timers = new uint[20];
PlayerWork playerWork = new PlayerWork();
public ushort currentJob;
public uint currentTitle;
public byte gcCurrent;
public byte gcRankLimsa;
public byte gcRankGridania;
public byte gcRankUldah;
public bool hasChocobo;
public bool hasGoobbue;
public byte chocoboAppearance;
public string chocoboName;
public uint achievementPoints;
public PlayerWork playerWork = new PlayerWork();
public Player(uint actorID) : base(actorID)
{
@ -47,58 +64,54 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
className = "Player";
currentSubState = SetActorStatePacket.SUB_STATE_PLAYER;
DBStats stats = Database.getCharacterStats(actorID);
charaWork.property[0] = 1;
charaWork.property[1] = 1;
charaWork.property[2] = 1;
charaWork.property[4] = 1;
charaWork.property[4] = 1;
charaWork.parameterSave.hp[0] = stats.hp;
charaWork.parameterSave.hpMax[0] = stats.hpMax;
charaWork.parameterSave.mp = stats.mp;
charaWork.parameterSave.mpMax = stats.mpMax;
charaWork.command[0] = 0xA0F00000 | 21001;
charaWork.command[1] = 0xA0F00000 | 21002;
charaWork.command[2] = 0xA0F00000 | 12003;
charaWork.command[3] = 0xA0F00000 | 12004;
charaWork.command[4] = 0xA0F00000 | 21005;
charaWork.command[5] = 0xA0F00000 | 21006;
charaWork.command[6] = 0xA0F00000 | 21007;
charaWork.command[7] = 0xA0F00000 | 12009;
charaWork.command[8] = 0xA0F00000 | 12010;
charaWork.command[9] = 0xA0F00000 | 12005;
charaWork.command[10] = 0xA0F00000 | 12007;
charaWork.command[11] = 0xA0F00000 | 12011;
charaWork.command[12] = 0xA0F00000 | 22012;
charaWork.command[13] = 0xA0F00000 | 22013;
charaWork.command[14] = 0xA0F00000 | 29497;
charaWork.command[15] = 0xA0F00000 | 22015;
charaWork.parameterSave.state_mainSkill[0] = 3;
charaWork.parameterSave.state_mainSkillLevel = 1;
charaWork.command[32] = 0xA0F00000 | 27155;
//charaWork.command[33] = 0xA0F00000 | 27150;
charaWork.command[34] = 0xA0F00000 | 27300;
charaWork.battleSave.skillLevel = 1;
charaWork.battleSave.skillLevelCap = 2;
charaWork.battleSave.potencial = 0.5f;
charaWork.battleSave.physicalExp = 1;
charaWork.battleSave.negotiationFlag[0] = false;
charaWork.battleSave.negotiationFlag[1] = false;
charaWork.commandAcquired[27150 - 26000] = true;
for (int i = 0; i < 20; i++)
charaWork.statusShownTime[i] = 0xFFFFFFFF;
playerWork.questScenarioComplete[110001 - 110001] = true;
playerWork.questGuildleveComplete[120050 - 120001] = true;
for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++ )
charaWork.additionalCommandAcquired[i] = true;
setPlayerAppearance();
for (int i = 0; i < charaWork.commandCategory.Length; i++)
charaWork.commandCategory[i] = 1;
charaWork.battleTemp.generalParameter[3] = 1;
charaWork.eventSave.bazaarTax = 5;
charaWork.battleSave.potencial = 6.6f;
charaWork.commandBorder = 0x20;
Database.loadPlayerCharacter(this);
}
public void setPlayerAppearance()
{
DBAppearance appearance = Database.getAppearance(true, actorId);
modelId = DBAppearance.getTribeModel(appearance.tribe);
appearanceIds[SIZE] = appearance.size;
appearanceIds[COLORINFO] = (uint)(appearance.skinColor | (appearance.hairColor << 10) | (appearance.eyeColor << 20));
appearanceIds[FACEINFO] = PrimitiveConversion.ToUInt32(appearance.getFaceInfo());
appearanceIds[HIGHLIGHT_HAIR] = (uint)(appearance.hairHighlightColor | appearance.hairStyle << 10);
appearanceIds[VOICE] = appearance.voice;
appearanceIds[WEAPON1] = appearance.mainHand;
appearanceIds[WEAPON2] = appearance.offHand;
appearanceIds[HEADGEAR] = appearance.head;
appearanceIds[BODYGEAR] = appearance.body;
appearanceIds[LEGSGEAR] = appearance.legs;
appearanceIds[HANDSGEAR] = appearance.hands;
appearanceIds[FEETGEAR] = appearance.feet;
appearanceIds[WAISTGEAR] = appearance.waist;
appearanceIds[R_EAR] = appearance.rightEar;
appearanceIds[L_EAR] = appearance.leftEar;
appearanceIds[R_FINGER] = appearance.rightFinger;
appearanceIds[L_FINGER] = appearance.leftFinger;
}
public List<SubPacket> create0x132Packets(uint playerActorId)
{
List<SubPacket> packets = new List<SubPacket>();
@ -125,7 +138,7 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams);
}
public override BasePacket getInitPackets(uint playerActorId)
public override BasePacket getSpawnPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(createAddActorPacket(playerActorId));
@ -141,14 +154,214 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
subpackets.Add(createInitStatusPacket(playerActorId));
subpackets.Add(createSetActorIconPacket(playerActorId));
subpackets.Add(createIsZoneingPacket(playerActorId));
subpackets.Add(createScriptBindPacket(playerActorId));
subpackets.AddRange(createPlayerRelatedPackets(playerActorId));
subpackets.Add(createScriptBindPacket(playerActorId));
return BasePacket.createPacket(subpackets, true, false);
}
public List<SubPacket> createPlayerRelatedPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
if (gcCurrent != 0)
subpackets.Add(SetGrandCompanyPacket.buildPacket(actorId, playerActorId, gcCurrent, gcRankLimsa, gcRankGridania, gcRankUldah));
if (currentTitle != 0)
subpackets.Add(SetPlayerTitlePacket.buildPacket(actorId, playerActorId, currentTitle));
if (currentJob != 0)
subpackets.Add(SetCurrentJobPacket.buildPacket(actorId, playerActorId, currentJob));
if (isMyPlayer(playerActorId))
{
subpackets.Add(_0x196Packet.buildPacket(playerActorId, playerActorId));
if (hasChocobo && chocoboName != null && !chocoboName.Equals(""))
{
subpackets.Add(SetChocoboNamePacket.buildPacket(actorId, playerActorId, chocoboName));
subpackets.Add(SetHasChocoboPacket.buildPacket(playerActorId, hasChocobo));
}
if (hasGoobbue)
subpackets.Add(SetHasGoobbuePacket.buildPacket(playerActorId, hasGoobbue));
subpackets.Add(SetAchievementPointsPacket.buildPacket(playerActorId, achievementPoints));
subpackets.Add(Database.getLatestAchievements(this));
subpackets.Add(Database.getAchievementsPacket(this));
/*
if (isInn)
{
SetCutsceneBookPacket book = new SetCutsceneBookPacket();
for (int i = 0; i < book.cutsceneFlags.Length; i++)
book.cutsceneFlags[i] = true;
client.queuePacket(book.buildPacket(player.actorID), true, false);
//
//subpackets.Add(SetPlayerDreamPacket.buildPacket(playerActorId, );
}
*/
}
return subpackets;
}
public override BasePacket getInitPackets(uint playerActorId)
{
ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("/_init", this, playerActorId);
propPacketUtil.addProperty("charaWork.eventSave.bazaarTax");
propPacketUtil.addProperty("charaWork.battleSave.potencial");
//Properties
for (int i = 0; i < charaWork.property.Length; i++)
{
if (charaWork.property[i] != 0)
propPacketUtil.addProperty(String.Format("charaWork.property[{0}]", i));
}
//Parameters
propPacketUtil.addProperty("charaWork.parameterSave.hp[0]");
propPacketUtil.addProperty("charaWork.parameterSave.hpMax[0]");
propPacketUtil.addProperty("charaWork.parameterSave.mp");
propPacketUtil.addProperty("charaWork.parameterSave.mpMax");
propPacketUtil.addProperty("charaWork.parameterTemp.tp");
propPacketUtil.addProperty("charaWork.parameterSave.state_mainSkill[0]");
propPacketUtil.addProperty("charaWork.parameterSave.state_mainSkillLevel");
//Status Times
for (int i = 0; i < charaWork.statusShownTime.Length; i++)
{
if (charaWork.statusShownTime[i] != 0xFFFFFFFF)
propPacketUtil.addProperty(String.Format("charaWork.statusShownTime[{0}]", i));
}
//General Parameters
for (int i = 3; i < charaWork.battleTemp.generalParameter.Length; i++)
{
if (charaWork.battleTemp.generalParameter[i] != 0)
propPacketUtil.addProperty(String.Format("charaWork.battleTemp.generalParameter[{0}]", i));
}
propPacketUtil.addProperty("charaWork.battleTemp.castGauge_speed[0]");
propPacketUtil.addProperty("charaWork.battleTemp.castGauge_speed[1]");
//Battle Save Skillpoint
//Commands
propPacketUtil.addProperty("charaWork.commandBorder");
for (int i = 0; i < charaWork.command.Length; i++)
{
if (charaWork.command[i] != 0)
propPacketUtil.addProperty(String.Format("charaWork.command[{0}]", i));
}
/*
for (int i = 0; i < charaWork.commandCategory.Length; i++)
{
charaWork.commandCategory[i] = 1;
if (charaWork.commandCategory[i] != 0)
propPacketUtil.addProperty(String.Format("charaWork.commandCategory[{0}]", i));
}
for (int i = 0; i < charaWork.commandAcquired.Length; i++)
{
if (charaWork.commandAcquired[i] != false)
propPacketUtil.addProperty(String.Format("charaWork.commandAcquired[{0}]", i));
}
*/
for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++)
{
if (charaWork.additionalCommandAcquired[i] != false)
propPacketUtil.addProperty(String.Format("charaWork.additionalCommandAcquired[{0}]", i));
}
for (int i = 0; i < charaWork.parameterSave.commandSlot_compatibility.Length; i++)
{
charaWork.parameterSave.commandSlot_compatibility[i] = true;
if (charaWork.parameterSave.commandSlot_compatibility[i])
propPacketUtil.addProperty(String.Format("charaWork.parameterSave.commandSlot_compatibility[{0}]", i));
}
/*
for (int i = 0; i < charaWork.parameterSave.commandSlot_recastTime.Length; i++)
{
if (charaWork.parameterSave.commandSlot_recastTime[i] != 0)
propPacketUtil.addProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i));
}
*/
//System
propPacketUtil.addProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[0]");
propPacketUtil.addProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[1]");
propPacketUtil.addProperty("charaWork.parameterTemp.forceControl_int16_forClientSelf[0]");
propPacketUtil.addProperty("charaWork.parameterTemp.forceControl_int16_forClientSelf[1]");
charaWork.parameterTemp.otherClassAbilityCount[0] = 4;
charaWork.parameterTemp.otherClassAbilityCount[1] = 5;
charaWork.parameterTemp.giftCount[1] = 5;
propPacketUtil.addProperty("charaWork.parameterTemp.otherClassAbilityCount[0]");
propPacketUtil.addProperty("charaWork.parameterTemp.otherClassAbilityCount[1]");
propPacketUtil.addProperty("charaWork.parameterTemp.giftCount[1]");
propPacketUtil.addProperty("charaWork.depictionJudge");
//Scenario
for (int i = 0; i < playerWork.questScenario.Length; i++)
{
if (playerWork.questScenario[i] != 0)
propPacketUtil.addProperty(String.Format("playerWork.questScenario[{0}]", i));
}
//Guildleve - Local
for (int i = 0; i < playerWork.questGuildleve.Length; i++)
{
if (playerWork.questGuildleve[i] != 0)
propPacketUtil.addProperty(String.Format("playerWork.questGuildleve[{0}]", i));
}
//Guildleve - Regional
for (int i = 0; i < work.guildleveId.Length; i++)
{
if (work.guildleveId[i] != 0)
propPacketUtil.addProperty(String.Format("work.guildleveId[{0}]", i));
if (work.guildleveDone[i] != false)
propPacketUtil.addProperty(String.Format("work.guildleveDone[{0}]", i));
if (work.guildleveChecked[i] != false)
propPacketUtil.addProperty(String.Format("work.guildleveChecked[{0}]", i));
}
//NPC Linkshell
for (int i = 0; i < playerWork.npcLinkshellChatCalling.Length; i++)
{
if (playerWork.npcLinkshellChatCalling[i] != false)
propPacketUtil.addProperty(String.Format("playerWork.npcLinkshellChatCalling[{0}]", i));
if (playerWork.npcLinkshellChatExtra[i] != false)
propPacketUtil.addProperty(String.Format("playerWork.npcLinkshellChatExtra[{0}]", i));
}
propPacketUtil.addProperty("playerWork.restBonusExpRate");
//Profile
propPacketUtil.addProperty("playerWork.tribe");
propPacketUtil.addProperty("playerWork.guardian");
propPacketUtil.addProperty("playerWork.birthdayMonth");
propPacketUtil.addProperty("playerWork.birthdayDay");
propPacketUtil.addProperty("playerWork.initialTown");
return propPacketUtil.done();
}
public bool isMyPlayer(uint otherActorId)
{
return actorId == otherActorId;
}
}
}
}

View File

@ -8,19 +8,19 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
{
class PlayerWork
{
public int tribe;
public int guardian;
public int birthdayMonth;
public int birthdayDay;
public int initialTown;
public byte tribe;
public byte guardian;
public byte birthdayMonth;
public byte birthdayDay;
public byte initialTown;
public int restBonusExpRate;
public float restBonusExpRate = 1.5f;
public int[] questScenario = new int[16];
public int[] questGuildLeve = new int[8];
public uint[] questScenario = new uint[16];
public uint[] questGuildleve = new uint[8];
public int questScenarioComplete;
public int questGuildleveComplete;
public bool[] questScenarioComplete = new bool[2048];
public bool[] questGuildleveComplete = new bool[2048];
public bool isContentsCommand;
@ -28,24 +28,24 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
public int castEndClient;
public int[] comboNextCommandId = new int[2];
public int comboCostBonusRate;
public float comboCostBonusRate;
public bool isRemainBonusPoint;
public int[] npcLinkshellChatCalling = new int[64];
public int[] npcLinkshellChatExtra = new int[64];
public bool[] npcLinkshellChatCalling = new bool[64];
public bool[] npcLinkshellChatExtra = new bool[64];
public int variableCommandConfirmWarp;
public int variableCommandConfirmWarpSender;
public string variableCommandConfirmWarpSender;
public int variableCommandConfirmWarpSenderByID;
public int variableCommandConfirmWarpSenderSex;
public byte variableCommandConfirmWarpSenderSex;
public int variableCommandConfirmWarpPlace;
public int variableCommandConfirmRaise;
public int variableCommandConfirmRaiseSender;
public string variableCommandConfirmRaiseSender;
public int variableCommandConfirmRaiseSenderByID;
public int variableCommandConfirmRaiseSenderSex;
public byte variableCommandConfirmRaiseSenderSex;
public int variableCommandConfirmRaisePlace;
}
}

View File

@ -0,0 +1,47 @@
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.debug
{
class DebugProg : Actor
{
public DebugProg()
: base(0x5FF80002)
{
this.displayNameId = 0;
this.customDisplayName = "debug";
this.actorName = "debug";
this.className = "Debug";
}
public override SubPacket createScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.createLuaParamList("/System/Debug.prog", false, false, false, false, true, 0xC51F, true, true);
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams);
}
public override BasePacket getSpawnPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(createAddActorPacket(playerActorId));
subpackets.Add(createSpeedPacket(playerActorId));
subpackets.Add(createSpawnPositonPacket(playerActorId, 0x1));
subpackets.Add(createNamePacket(playerActorId));
subpackets.Add(createStatePacket(playerActorId));
subpackets.Add(createIsZoneingPacket(playerActorId));
subpackets.Add(createScriptBindPacket(playerActorId));
return BasePacket.createPacket(subpackets, true, false);
}
}
}

View File

@ -0,0 +1,49 @@
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.director
{
class WeatherDirector : Actor
{
private uint weatherId;
public WeatherDirector(uint weatherId, Zone zone)
: base(0x5FF80002)
{
this.weatherId = weatherId;
this.displayNameId = 0;
this.customDisplayName = String.Format("weatherDire_{0}", zone.zoneName, zone.actorId);
this.actorName = String.Format("weatherDire_{0}@{0:04x}", zone.zoneName, zone.actorId);
this.className = "Debug";
}
public override SubPacket createScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.createLuaParamList("/Director/Weather/WeatherDirector", false, false, false, false, weatherId);
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams);
}
public override BasePacket getSpawnPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(createAddActorPacket(playerActorId));
subpackets.Add(createSpeedPacket(playerActorId));
subpackets.Add(createSpawnPositonPacket(playerActorId, 0x1));
subpackets.Add(createNamePacket(playerActorId));
subpackets.Add(createStatePacket(playerActorId));
subpackets.Add(createIsZoneingPacket(playerActorId));
subpackets.Add(createScriptBindPacket(playerActorId));
return BasePacket.createPacket(subpackets, true, false);
}
}
}

View File

@ -0,0 +1,44 @@
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.world
{
class WorldMaster : Actor
{
public WorldMaster() : base(0x5FF80001)
{
this.displayNameId = 0;
this.customDisplayName = "worldMaster";
this.actorName = "worldMaster";
this.className = "WorldMaster";
}
public override SubPacket createScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.createLuaParamList("/World/WorldMaster_event", false, false, false, false, false, null);
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams);
}
public override BasePacket getSpawnPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(createAddActorPacket(playerActorId));
subpackets.Add(createSpeedPacket(playerActorId));
subpackets.Add(createSpawnPositonPacket(playerActorId, 0x1));
subpackets.Add(createNamePacket(playerActorId));
subpackets.Add(createStatePacket(playerActorId));
subpackets.Add(createIsZoneingPacket(playerActorId));
subpackets.Add(createScriptBindPacket(playerActorId));
return BasePacket.createPacket(subpackets, true, false);
}
}
}

View File

@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.common
{
namespace EfficientHashTables
{
public class Efficient64bitHashTable<T>
{
private class element
{
public ulong _key;
public T _value;
};
private element[][] _buckets;
private uint _capacity;
public Efficient64bitHashTable()
{
_capacity = 214373; // some prime number
_buckets = new element[_capacity][];
}
public Efficient64bitHashTable(uint capacity)
{
_capacity = capacity;
_buckets = new element[_capacity][];
}
public uint hash(ulong key)
{
return (uint)(key % _capacity);
}
public void Add(ulong key, T value)
{
uint hsh = hash(key);
element[] e;
if (_buckets[hsh] == null)
_buckets[hsh] = e = new element[1];
else
{
foreach (var elem in _buckets[hsh])
if (elem._key == key)
{
elem._value = value;
return;
}
e = new element[_buckets[hsh].Length + 1];
Array.Copy(_buckets[hsh], 0, e, 1, _buckets[hsh].Length);
_buckets[hsh] = e;
}
e[0] = new element { _key = key, _value = value };
}
public T Get(ulong key)
{
uint hsh = hash(key);
element[] e = _buckets[hsh];
if (e == null) return default(T);
foreach (var f in e)
if (f._key == key)
return f._value;
return default(T);
}
public bool Has(ulong key)
{
uint hsh = hash(key);
element[] e = _buckets[hsh];
if (e == null) return false;
foreach (var f in e)
if (f._key == key)
return true;
return false;
}
public int Count()
{
int r = 0;
foreach (var e in _buckets)
if (e != null)
r += e.Length;
return r;
}
}
public class Efficient32bitHashTable<T>
{
private class element
{
public uint _key;
public T _value;
};
private element[][] _buckets;
private uint _capacity;
public Efficient32bitHashTable()
{
_capacity = 463; // some prime number
_buckets = new element[_capacity][];
}
public Efficient32bitHashTable(uint capacity)
{
_capacity = capacity;
_buckets = new element[_capacity][];
}
public uint hash(uint key)
{
return (uint)(key % _capacity);
}
public void Add(uint key, T value)
{
uint hsh = hash(key);
element[] e;
if (_buckets[hsh] == null)
_buckets[hsh] = e = new element[1];
else
{
foreach (var elem in _buckets[hsh])
if (elem._key == key)
{
elem._value = value;
return;
}
e = new element[_buckets[hsh].Length + 1];
Array.Copy(_buckets[hsh], 0, e, 1, _buckets[hsh].Length);
_buckets[hsh] = e;
}
e[0] = new element { _key = key, _value = value };
}
public T Get(uint key)
{
uint hsh = hash(key);
element[] e = _buckets[hsh];
if (e == null) return default(T);
foreach (var f in e)
if (f._key == key)
return f._value;
return default(T);
}
public int Count()
{
int r = 0;
foreach (var e in _buckets)
if (e != null)
r += e.Length;
return r;
}
}
}
}

View File

@ -1,314 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Lobby_Server.common;
using System.IO;
namespace FFXIVClassic_Lobby_Server.dataobjects
{
class CharaInfo
{
public uint tribe = 0;
public uint size = 0;
public uint voice = 0;
public ushort skinColor = 0;
public ushort hairStyle = 0;
public ushort hairColor = 0;
public ushort hairHighlightColor = 0;
public ushort eyeColor = 0;
public ushort characteristicsColor = 0;
public struct FaceInfo
{
[BitfieldLength(5)]
public uint characteristics;
[BitfieldLength(3)]
public uint characteristicsColor;
[BitfieldLength(6)]
public uint type;
[BitfieldLength(2)]
public uint ears;
[BitfieldLength(2)]
public uint mouth;
[BitfieldLength(2)]
public uint features;
[BitfieldLength(3)]
public uint nose;
[BitfieldLength(3)]
public uint eyeShape;
[BitfieldLength(1)]
public uint irisSize;
[BitfieldLength(3)]
public uint eyebrows;
[BitfieldLength(2)]
public uint unknown;
}
public uint faceType = 0;
public uint faceEyebrows = 0;
public uint faceEyeShape = 0;
public uint faceIrisSize = 0;
public uint faceNose = 0;
public uint faceMouth = 0;
public uint faceFeatures = 0;
public uint characteristics = 0;
public uint ears = 0;
public uint guardian = 0;
public uint birthMonth = 0;
public uint birthDay = 0;
public uint currentClass = 0;
public uint currentJob = 0;
public uint allegiance = 0;
public uint mainHand = 0;
public uint offHand = 0;
public uint headGear = 0;
public uint bodyGear = 0;
public uint legsGear = 0;
public uint handsGear = 0;
public uint feetGear = 0;
public uint waistGear = 0;
public uint rightEarGear = 0;
public uint leftEarGear = 0;
public uint rightFingerGear = 0;
public uint leftFingerGear = 0;
public uint currentLevel = 1;
public static CharaInfo getFromNewCharRequest(String encoded)
{
byte[] data = Convert.FromBase64String(encoded.Replace('-', '+').Replace('_', '/'));
CharaInfo info = new CharaInfo();
using (MemoryStream stream = new MemoryStream(data))
{
using (BinaryReader reader = new BinaryReader(stream))
{
uint version = reader.ReadUInt32();
uint unknown1 = reader.ReadUInt32();
info.tribe = reader.ReadByte();
info.size = reader.ReadByte();
info.hairStyle = reader.ReadUInt16();
info.hairHighlightColor = reader.ReadUInt16();
info.faceType = reader.ReadByte();
info.characteristics = reader.ReadByte();
info.characteristicsColor = reader.ReadByte();
reader.ReadUInt32();
info.faceEyebrows = reader.ReadByte();
info.faceIrisSize = reader.ReadByte();
info.faceEyeShape = reader.ReadByte();
info.faceNose = reader.ReadByte();
info.faceFeatures = reader.ReadByte();
info.faceMouth = reader.ReadByte();
info.ears = reader.ReadByte();
info.hairColor = reader.ReadUInt16();
reader.ReadUInt32();
info.skinColor = reader.ReadUInt16();
info.eyeColor = reader.ReadUInt16();
info.voice = reader.ReadByte();
info.guardian = reader.ReadByte();
info.birthMonth = reader.ReadByte();
info.birthDay = reader.ReadByte();
info.currentClass = reader.ReadUInt16();
reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
reader.BaseStream.Seek(0x10, SeekOrigin.Current);
info.allegiance = reader.ReadByte();
}
}
return info;
}
public String buildForCharaList(DBCharacter chara)
{
byte[] data;
mainHand = 79707136;
offHand = 32509954;
headGear = 43008;
bodyGear = 43008;
legsGear = 43008;
handsGear = 43008;
feetGear = 43008;
using (MemoryStream stream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
//Build faceinfo for later
FaceInfo faceInfo = new FaceInfo();
faceInfo.characteristics = characteristics;
faceInfo.characteristicsColor = characteristicsColor;
faceInfo.type = faceType;
faceInfo.ears = ears;
faceInfo.features = faceFeatures;
faceInfo.eyebrows = faceEyebrows;
faceInfo.eyeShape = faceEyeShape;
faceInfo.irisSize = faceIrisSize;
faceInfo.mouth = faceMouth;
faceInfo.nose = faceNose;
string location1 = "prv0Inn01\0";
string location2 = "defaultTerritory\0";
writer.Write((UInt32)0x000004c0);
writer.Write((UInt32)0x232327ea);
writer.Write((UInt32)System.Text.Encoding.UTF8.GetBytes(chara.name + '\0').Length);
writer.Write(System.Text.Encoding.UTF8.GetBytes(chara.name + '\0'));
writer.Write((UInt32)0x1c);
writer.Write((UInt32)0x04);
writer.Write((UInt32)getTribeModel());
writer.Write((UInt32)size);
uint colorVal = skinColor | (uint)(hairColor << 10) | (uint)(eyeColor << 20);
writer.Write((UInt32)colorVal);
var bitfield = PrimitiveConversion.ToUInt32(faceInfo);
writer.Write((UInt32)bitfield); //FACE, Figure this out!
uint hairVal = hairHighlightColor | (uint)(hairStyle << 10) | (uint)(characteristicsColor << 20);
writer.Write((UInt32)hairVal);
writer.Write((UInt32)voice);
writer.Write((UInt32)mainHand);
writer.Write((UInt32)offHand);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)headGear);
writer.Write((UInt32)bodyGear);
writer.Write((UInt32)legsGear);
writer.Write((UInt32)handsGear);
writer.Write((UInt32)feetGear);
writer.Write((UInt32)waistGear);
writer.Write((UInt32)0);
writer.Write((UInt32)rightEarGear);
writer.Write((UInt32)leftEarGear);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)rightFingerGear);
writer.Write((UInt32)leftFingerGear);
for (int i = 0; i < 0x8; i++)
writer.Write((byte)0);
writer.Write((UInt32)1);
writer.Write((UInt32)1);
writer.Write((byte)currentClass);
writer.Write((UInt16)currentLevel);
writer.Write((byte)currentJob);
writer.Write((UInt16)1);
writer.Write((byte)tribe);
writer.Write((UInt32)0xe22222aa);
writer.Write((UInt32)System.Text.Encoding.UTF8.GetBytes(location1).Length);
writer.Write(System.Text.Encoding.UTF8.GetBytes(location1));
writer.Write((UInt32)System.Text.Encoding.UTF8.GetBytes(location2).Length);
writer.Write(System.Text.Encoding.UTF8.GetBytes(location2));
writer.Write((byte)guardian);
writer.Write((byte)birthMonth);
writer.Write((byte)birthDay);
writer.Write((UInt16)0x17);
writer.Write((UInt32)4);
writer.Write((UInt32)4);
writer.BaseStream.Seek(0x10, SeekOrigin.Current);
writer.Write((UInt32)allegiance);
writer.Write((UInt32)allegiance);
}
data = stream.GetBuffer();
}
return Convert.ToBase64String(data).Replace('+', '-').Replace('/', '_');
}
public static String debug()
{
byte[] bytes = File.ReadAllBytes("./packets/charaInfo.bin");
Console.WriteLine(Utils.ByteArrayToHex(bytes));
return Convert.ToBase64String(bytes).Replace('+', '-').Replace('/', '_');
}
public UInt32 getTribeModel()
{
switch (tribe)
{
//Hyur Midlander Male
case 1:
default:
return 1;
//Hyur Midlander Female
case 2:
return 2;
//Elezen Male
case 4:
case 6:
return 3;
//Elezen Female
case 5:
case 7:
return 4;
//Lalafell Male
case 8:
case 10:
return 5;
//Lalafell Female
case 9:
case 11:
return 6;
//Miqo'te Female
case 12:
case 13:
return 8;
//Roegadyn Male
case 14:
case 15:
return 7;
//Hyur Highlander Male
case 3:
return 9;
}
}
}
}

View File

@ -1,5 +1,4 @@
using FFXIVClassic_Lobby_Server;
using FFXIVClassic_Lobby_Server.dataobjects;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.packets.send.actor;
@ -28,8 +27,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
public ConnectedPlayer(uint actorId)
{
this.actorID = actorId;
DBCharacter chara = Database.getCharacter(actorId);
createPlayerActor(actorId, chara);
playerActor = new Player(actorId);
actorInstanceList.Add(playerActor);
}
public void addConnection(ClientConnection conn)
@ -89,16 +88,6 @@ namespace FFXIVClassic_Map_Server.dataobjects
return playerActor;
}
public void createPlayerActor(uint actorId, DBCharacter chara)
{
playerActor = new Player(actorId);
playerActor.displayNameId = 0xFFFFFFFF;
playerActor.customDisplayName = chara.name;
playerActor.setPlayerAppearance();
actorInstanceList.Add(playerActor);
}
public void updatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState)
{
/*
@ -112,8 +101,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
public void sendMotd()
{
DBWorld world = Database.getServer(ConfigConstants.DATABASE_WORLDID);
//sendChat(world.motd);
}
public void sendChat(ConnectedPlayer sender, string message, int mode)

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Lobby_Server.dataobjects
{
class DBWorld
{
public ushort id;
public string address;
public ushort port;
public ushort listPosition;
public ushort population;
public string name;
public bool isActive;
public string motd;
}
}

View File

@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.dataobjects;
namespace FFXIVClassic_Lobby_Server
{
class DBCharacter
{
public uint id;
public ushort slot;
public ushort serverId;
public string name;
public ushort state;
public string charaInfo;
public bool isLegacy;
public bool doRename;
public uint currentZoneId;
public static CharaInfo EncodedToCharacter(String charaInfo)
{
charaInfo.Replace("+", "-");
charaInfo.Replace("/", "_");
byte[] data = System.Convert.FromBase64String(charaInfo);
Console.WriteLine("------------Base64 printout------------------");
Console.WriteLine(Utils.ByteArrayToHex(data));
Console.WriteLine("------------Base64 printout------------------");
CharaInfo chara = new CharaInfo();
return chara;
}
}
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.dataobjects.database
{
class DBCommands
{
public uint classId;
public uint index;
public uint commandId;
public uint recastTime;
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.dataobjects.database
{
class DBJournal
{
public uint id;
public uint characterId;
public uint index;
public uint questId;
public uint type;
public bool abandoned;
public bool completed;
}
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.dataobjects.database
{
class DBPlayerData
{
public int tribe;
public int guardian;
public int birthdayMonth;
public int birthdayDay;
public int initialTown;
}
}

View File

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.dataobjects.database
{
class DBStats
{
public int hp;
public int hpMax;
public int mp;
public int mpMax;
public ushort[] state_mainSkill;
public int state_mainSkillLevel;
}
}

View File

@ -195,7 +195,7 @@ namespace FFXIVClassic_Map_Server
foreach (object o in list)
{
if (o.GetType().IsArray)
if (o != null && o.GetType().IsArray)
{
Array arrayO = (Array)o;
foreach (object o2 in arrayO)

View File

@ -6,7 +6,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.send.Actor
namespace FFXIVClassic_Map_Server.packets.send.actor
{
class SetActorNamePacket
{
@ -23,7 +23,7 @@ namespace FFXIVClassic_Map_Server.packets.send.Actor
{
binWriter.Write((UInt32)displayNameID);
if (displayNameID == 0xFFFFFFFF)
if (displayNameID == 0 || displayNameID == 0xFFFFFFFF)
{
binWriter.Write(Encoding.ASCII.GetBytes(customName), 0, Encoding.ASCII.GetByteCount(customName) >= 0x20 ? 0x19 : Encoding.ASCII.GetByteCount(customName));
}

View File

@ -22,14 +22,17 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
private byte[] data = new byte[PACKET_SIZE - 0x20];
private bool isMore = false;
string currentTarget;
private MemoryStream mem;
private BinaryWriter binWriter;
public SetActorPropetyPacket()
public SetActorPropetyPacket(string startingTarget)
{
mem = new MemoryStream(data);
binWriter = new BinaryWriter(mem);
binWriter.Seek(1, SeekOrigin.Begin);
currentTarget = startingTarget;
}
public void closeStreams()
@ -40,7 +43,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
public bool addByte(uint id, byte value)
{
if (runningByteTotal + 6 > MAXBYTES)
if (runningByteTotal + 6 + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES)
return false;
binWriter.Write((byte)1);
@ -53,7 +56,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
public bool addShort(uint id, ushort value)
{
if (runningByteTotal + 7 > MAXBYTES)
if (runningByteTotal + 7 + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES)
return false;
binWriter.Write((byte)2);
@ -66,7 +69,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
public bool addInt(uint id, uint value)
{
if (runningByteTotal + 9 > MAXBYTES)
if (runningByteTotal + 9 + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES)
return false;
binWriter.Write((byte)4);
@ -79,7 +82,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
public bool addBuffer(uint id, byte[] buffer)
{
if (runningByteTotal + 5 + buffer.Length > MAXBYTES)
if (runningByteTotal + 5 + buffer.Length + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES)
return false;
binWriter.Write((byte)buffer.Length);
@ -90,13 +93,13 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
return true;
}
public void addProperty(FFXIVClassic_Map_Server.dataobjects.Actor actor, string name)
public bool addProperty(FFXIVClassic_Map_Server.dataobjects.Actor actor, string name)
{
string[] split = name.Split('.');
int arrayIndex = 0;
if (!(split[0].Equals("work") || split[0].Equals("charaWork") || split[0].Equals("playerWork") || split[0].Equals("npcWork")))
return;
return false;
Object curObj = actor;
for (int i = 0; i < split.Length; i++)
@ -105,54 +108,54 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
if (split[i].Contains('['))
{
if (split[i].LastIndexOf(']') - split[i].IndexOf('[') <= 0)
return;
return false;
arrayIndex = Convert.ToInt32(split[i].Substring(split[i].IndexOf('[') + 1, split[i].Length - split[i].LastIndexOf(']')));
arrayIndex = Convert.ToInt32(split[i].Substring(split[i].IndexOf('[') + 1, split[i].LastIndexOf(']') - split[i].LastIndexOf('[')-1));
split[i] = split[i].Substring(0, split[i].IndexOf('['));
}
FieldInfo field = curObj.GetType().GetField(split[i]);
if (field == null)
return;
return false;
curObj = field.GetValue(curObj);
if (curObj == null)
return;
return false;
}
if (curObj == null)
return;
return false;
else
{
//Array, we actually care whats inside
if (curObj.GetType().IsArray)
{
if (((Array)curObj).Length <= arrayIndex)
return;
return false;
curObj = ((Array)curObj).GetValue(arrayIndex);
}
if (curObj == null)
return;
return false;
//Cast to the proper object and add to packet
uint id = Utils.MurmurHash2(name, 0);
if (curObj is bool)
addByte(id, (byte)(((bool)curObj) ? 1 : 0));
return addByte(id, (byte)(((bool)curObj) ? 1 : 0));
else if (curObj is byte)
addByte(id, (byte)curObj);
return addByte(id, (byte)curObj);
else if (curObj is ushort)
addShort(id, (ushort)curObj);
else if (curObj is short)
addShort(id, (ushort)(short)curObj);
return addShort(id, (ushort)curObj);
else if (curObj is short)
return addShort(id, (ushort)(short)curObj);
else if (curObj is uint)
addInt(id, (uint)curObj);
else if (curObj is int)
addInt(id, (uint)(int)curObj);
return addInt(id, (uint)curObj);
else if (curObj is int)
return addInt(id, (uint)(int)curObj);
else if (curObj is float)
addBuffer(id, BitConverter.GetBytes((float)curObj));
return addBuffer(id, BitConverter.GetBytes((float)curObj));
else
return;
return false;
}
}
@ -163,10 +166,22 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
public void setTarget(string target)
{
binWriter.Write((byte)(isMore ? 0x62 + target.Length : 0x82 + target.Length));
binWriter.Write(Encoding.ASCII.GetBytes(target));
runningByteTotal += (ushort)(1 + Encoding.ASCII.GetByteCount(target));
currentTarget = target;
}
public void addTarget()
{
binWriter.Write((byte)(isMore ? 0x60 + currentTarget.Length : 0x82 + currentTarget.Length));
binWriter.Write(Encoding.ASCII.GetBytes(currentTarget));
runningByteTotal += (ushort)(1 + Encoding.ASCII.GetByteCount(currentTarget));
}
public void addTarget(string newTarget)
{
binWriter.Write((byte)(isMore ? 0x60 + currentTarget.Length : 0x82 + currentTarget.Length));
binWriter.Write(Encoding.ASCII.GetBytes(currentTarget));
runningByteTotal += (ushort)(1 + Encoding.ASCII.GetByteCount(currentTarget));
currentTarget = newTarget;
}
public SubPacket buildPacket(uint playerActorID, uint actorID)
@ -176,7 +191,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
closeStreams();
SubPacket packet = new SubPacket(OPCODE, playerActorID, actorID, data);
SubPacket packet = new SubPacket(OPCODE, actorID, playerActorID, data);
return packet;
}

View File

@ -24,7 +24,7 @@ namespace FFXIVClassic_Map_Server.packets.send.player
public const int CATEGORY_DUNGEONS = 750;
public const int CATEGORY_EXPLORATION = 800;
public const int CATEGORY_GRAND_COMPANY = 820;
public const ushort OPCODE = 0x019A;
public const uint PACKET_SIZE = 0xA0;
@ -48,6 +48,6 @@ namespace FFXIVClassic_Map_Server.packets.send.player
return new SubPacket(OPCODE, playerActorID, playerActorID, data);
}
}
}

View File

@ -20,11 +20,11 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
using (MemoryStream mem = new MemoryStream(data))
{
using (BinaryWriter binWriter = new BinaryWriter(mem))
{
binWriter.Write((UInt16)currentAllegiance);
binWriter.Write((UInt16)rankLimsa);
binWriter.Write((UInt16)rankGridania);
binWriter.Write((UInt16)rankUldah);
{
binWriter.Write((Byte)currentAllegiance);
binWriter.Write((Byte)rankLimsa);
binWriter.Write((Byte)rankGridania);
binWriter.Write((Byte)rankUldah);
}
}

View File

@ -0,0 +1,48 @@
using FFXIVClassic_Lobby_Server.packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.dataobjects;
namespace FFXIVClassic_Map_Server.utils
{
class ActorPropertyPacketUtil
{
Actor forActor;
uint playerActorId;
List<SubPacket> subPackets = new List<SubPacket>();
SetActorPropetyPacket currentActorPropertyPacket;
string currentTarget;
public ActorPropertyPacketUtil(string firstTarget, Actor forActor, uint playerActorId)
{
currentActorPropertyPacket = new SetActorPropetyPacket(firstTarget);
this.forActor = forActor;
this.playerActorId = playerActorId;
this.currentTarget = firstTarget;
}
public void addProperty(string property)
{
if (!currentActorPropertyPacket.addProperty(forActor, property))
{
currentActorPropertyPacket.setIsMore(true);
currentActorPropertyPacket.addTarget();
subPackets.Add(currentActorPropertyPacket.buildPacket(playerActorId, forActor.actorId));
currentActorPropertyPacket = new SetActorPropetyPacket(currentTarget);
}
}
public BasePacket done()
{
currentActorPropertyPacket.addTarget();
currentActorPropertyPacket.setIsMore(false);
subPackets.Add(currentActorPropertyPacket.buildPacket(playerActorId, forActor.actorId));
return BasePacket.createPacket(subPackets, true, false);
}
}
}

View File

@ -5,49 +5,10 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Lobby_Server.dataobjects
namespace FFXIVClassic_Map_Server.utils
{
class DBAppearance
class CharacterUtils
{
////////////
//Chara Info
public byte tribe = 0;
public byte size = 0;
public byte voice = 0;
public ushort skinColor = 0;
public ushort hairStyle = 0;
public ushort hairColor = 0;
public ushort hairHighlightColor = 0;
public ushort eyeColor = 0;
public byte characteristicsColor = 0;
public byte faceType = 0;
public byte faceEyebrows = 0;
public byte faceEyeShape = 0;
public byte faceIrisSize = 0;
public byte faceNose = 0;
public byte faceMouth = 0;
public byte faceFeatures = 0;
public byte characteristics = 0;
public byte ears = 0;
public uint mainHand = 0;
public uint offHand = 0;
public uint head = 0;
public uint body = 0;
public uint legs = 0;
public uint hands = 0;
public uint feet = 0;
public uint waist = 0;
public uint rightEar = 0;
public uint leftEar = 0;
public uint rightFinger = 0;
public uint leftFinger = 0;
//Chara Info
////////////
public struct FaceInfo
{
[BitfieldLength(5)]
@ -73,8 +34,8 @@ namespace FFXIVClassic_Lobby_Server.dataobjects
[BitfieldLength(2)]
public uint unknown;
}
public FaceInfo getFaceInfo()
public static FaceInfo getFaceInfo(byte characteristics, byte characteristicsColor, byte faceType, byte ears, byte faceMouth, byte faceFeatures, byte faceNose, byte faceEyeShape, byte faceIrisSize, byte faceEyebrows)
{
FaceInfo faceInfo = new FaceInfo();
faceInfo.characteristics = characteristics;

View File

@ -0,0 +1,362 @@
using FFXIVClassic_Lobby_Server;
using FFXIVClassic_Map_Server.packets.send.player;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.utils
{
class SQLGeneration
{
public static void generateItems()
{
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();
//Load Last 5 Completed
string query = @"
INSERT INTO gamedata_items VALUES (@id, @displayNameId, NULL)";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@id", 100);
cmd.Parameters.AddWithValue("@displayNameId", 100);
cmd.Prepare();
string line, line2;
Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled);
System.IO.StreamReader file = new System.IO.StreamReader("D:\\Coding\\FFXIV Related\\FFXIV Tool\\2012.09.19.0001.decode.csv\\actorclass.csv");
while ((line = file.ReadLine()) != null)
{
MatchCollection matches = csvSplit.Matches(line);
uint id;
uint nameId;
try
{
id = UInt32.Parse(matches[0].Value.Trim(','));
nameId = UInt32.Parse(matches[6].Value.Trim(','));
}
catch (FormatException e)
{ continue; }
cmd.Parameters["@id"].Value = id;
cmd.Parameters["@displayNameId"].Value = nameId;
Console.WriteLine("Wrote: {0} : {1}", id, nameId);
cmd.ExecuteNonQuery();
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
}
public static void generateZones()
{
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();
//Load Last 5 Completed
string query = @"
INSERT INTO server_zones VALUES (@id, NULL, @placename, false, false, false, false)";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@id", 100);
cmd.Parameters.AddWithValue("@placename", "");
cmd.Prepare();
Dictionary<uint, string> placenames = new Dictionary<uint, string>();
string line2;
Regex csvSplit2 = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled);
System.IO.StreamReader file2 = new System.IO.StreamReader("D:\\Coding\\FFXIV Related\\FFXIV Tool\\2012.09.19.0001.decode.csv\\xtx_placeName.csv");
while ((line2 = file2.ReadLine()) != null)
{
MatchCollection matches = csvSplit2.Matches(line2);
uint id;
string name;
try
{
id = UInt32.Parse(matches[0].Value.Trim(','));
name = matches[2].Value.Trim(',');
}
catch (FormatException e)
{ continue; }
placenames.Add(id, name);
}
string line;
Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled);
System.IO.StreamReader file = new System.IO.StreamReader("D:\\Coding\\FFXIV Related\\FFXIV Tool\\2012.09.19.0001.decode.csv\\_zoneParam.csv");
while ((line = file.ReadLine()) != null)
{
MatchCollection matches = csvSplit.Matches(line);
uint id;
uint pId;
try
{
id = UInt32.Parse(matches[0].Value.Trim(','));
pId = UInt32.Parse(matches[1].Value.Trim(','));
}
catch (FormatException e)
{ continue; }
cmd.Parameters["@id"].Value = id;
cmd.Parameters["@placename"].Value = placenames[pId];
Console.WriteLine("Wrote: {0}", id);
cmd.ExecuteNonQuery();
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
}
public static void generateActors()
{
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();
//Load Last 5 Completed
string query = @"
INSERT INTO gamedata_actor_templates VALUES (@id, @displayNameId, NULL)";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@id", 100);
cmd.Parameters.AddWithValue("@displayNameId", 100);
cmd.Prepare();
string line, line2;
Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled);
System.IO.StreamReader file = new System.IO.StreamReader("D:\\Coding\\FFXIV Related\\FFXIV Tool\\2012.09.19.0001.decode.csv\\actorclass.csv");
while ((line = file.ReadLine()) != null)
{
MatchCollection matches = csvSplit.Matches(line);
uint id;
uint nameId;
try
{
id = UInt32.Parse(matches[0].Value.Trim(','));
nameId = UInt32.Parse(matches[6].Value.Trim(','));
}
catch (FormatException e)
{ continue; }
cmd.Parameters["@id"].Value = id;
cmd.Parameters["@displayNameId"].Value = nameId;
Console.WriteLine("Wrote: {0} : {1}", id, nameId);
cmd.ExecuteNonQuery();
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
}
public static void generateActorAppearance()
{
uint NUMFIELDS = 39;
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();
//Load Last 5 Completed
string query = @"
INSERT INTO gamedata_actor_appearance VALUES (@id, ";
for (int i = 0; i < NUMFIELDS-1; i++)
query += "@v"+i+", ";
query += "@v" + (NUMFIELDS-1) + ")";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@id", 0);
for (int i = 0; i < NUMFIELDS; i++)
cmd.Parameters.AddWithValue("@v" + i, 100);
cmd.Prepare();
string line;
Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled);
//System.IO.StreamReader file = new System.IO.StreamReader("D:\\Coding\\FFXIV Related\\FFXIV Tool\\2012.09.19.0001.decode.csv\\actorclass.csv");
System.IO.StreamReader file = new System.IO.StreamReader("D:\\Coding\\FFXIV Related\\FFXIV Tool\\2012.09.19.0001.decode.csv\\actorclass_graphic.csv");
while ((line = file.ReadLine()) != null)
{
MatchCollection matches = csvSplit.Matches(line);
uint id;
try
{
id = UInt32.Parse(matches[0].Value.Trim(','));
for (int i = 0; i < NUMFIELDS; i++)
cmd.Parameters["@v" + i].Value = matches[i + 7].Value.Trim(',');
}
catch (FormatException e)
{ continue; }
cmd.Parameters["@id"].Value = id;
Console.WriteLine("Wrote: {0}", id);
cmd.ExecuteNonQuery();
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
}
public static void generateAchievementIds()
{
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();
//Load Last 5 Completed
string query = @"
INSERT INTO gamedata_achievements VALUES (@id, @name, @otherId, @rewardPoints)";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@id", 100);
cmd.Parameters.AddWithValue("@name", "Battle");
cmd.Parameters.AddWithValue("@otherId", 0);
cmd.Parameters.AddWithValue("@rewardPoints", 0);
cmd.Prepare();
int otherId = 1;
string line, line2;
Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled);
System.IO.StreamReader file = new System.IO.StreamReader("D:\\Coding\\FFXIV Related\\FFXIV Tool\\2012.09.19.0001.decode.csv\\achievement.csv");
System.IO.StreamReader file2 = new System.IO.StreamReader("D:\\Coding\\FFXIV Related\\FFXIV Tool\\2012.09.19.0001.decode.csv\\xtx_achievement.csv");
while ((line = file.ReadLine()) != null)
{
line2 = file2.ReadLine();
MatchCollection matches = csvSplit.Matches(line);
MatchCollection matches2 = csvSplit.Matches(line2);
uint id;
string name;
uint points;
try
{
id = UInt32.Parse(matches2[0].Value.Trim(','));
name = matches2[9].Value.Trim(',');
points = UInt32.Parse(matches[3].Value.Trim(','));
}
catch (FormatException e)
{ continue; }
if (id == 100)
otherId = SetCompletedAchievementsPacket.CATEGORY_BATTLE;
else if (id == 200)
otherId = SetCompletedAchievementsPacket.CATEGORY_CHARACTER;
else if (id == 400)
otherId = SetCompletedAchievementsPacket.CATEGORY_CURRENCY;
else if (id == 500)
otherId = SetCompletedAchievementsPacket.CATEGORY_ITEMS;
else if (id == 600)
otherId = SetCompletedAchievementsPacket.CATEGORY_SYNTHESIS;
else if (id == 700)
otherId = SetCompletedAchievementsPacket.CATEGORY_GATHERING;
else if (id == 900)
otherId = SetCompletedAchievementsPacket.CATEGORY_MATERIA;
else if (id == 1000)
otherId = SetCompletedAchievementsPacket.CATEGORY_QUESTS;
else if (id == 1200)
otherId = SetCompletedAchievementsPacket.CATEGORY_SEASONAL_EVENTS;
else if (id == 1300)
otherId = SetCompletedAchievementsPacket.CATEGORY_DUNGEONS;
else if (id == 1400)
otherId = SetCompletedAchievementsPacket.CATEGORY_EXPLORATION;
else if (id == 1500)
otherId = SetCompletedAchievementsPacket.CATEGORY_GRAND_COMPANY;
Console.WriteLine("Wrote: {0} : {1} : {2} : {3}", id, name, otherId, points);
cmd.Parameters["@id"].Value = id;
cmd.Parameters["@name"].Value = name;
cmd.Parameters["@otherId"].Value = otherId;
cmd.Parameters["@rewardPoints"].Value = points;
cmd.ExecuteNonQuery();
otherId++;
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
}
}
}