diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs
index c7f76045..e97597ef 100644
--- a/FFXIVClassic Map Server/Database.cs
+++ b/FFXIVClassic Map Server/Database.cs
@@ -204,6 +204,40 @@ namespace FFXIVClassic_Lobby_Server
}
}
+ public static void savePlayerCurrentClass(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();
+
+ query = @"
+ UPDATE characters_parametersave SET
+ mainSkill = @classId,
+ mainSkillLevel = @classLevel
+ WHERE characterId = @charaId
+ ";
+
+ cmd = new MySqlCommand(query, conn);
+ cmd.Parameters.AddWithValue("@charaId", player.actorId);
+ cmd.Parameters.AddWithValue("@classId", player.charaWork.parameterSave.state_mainSkill[0]);
+ cmd.Parameters.AddWithValue("@classLevel", player.charaWork.parameterSave.state_mainSkillLevel);
+
+ cmd.ExecuteNonQuery();
+ }
+ catch (MySqlException e)
+ { Console.WriteLine(e); }
+ finally
+ {
+ conn.Dispose();
+ }
+ }
+ }
+
public static void savePlayerPosition(Player player)
{
string query;
@@ -296,8 +330,7 @@ namespace FFXIVClassic_Lobby_Server
positionZ,
rotation,
actorState,
- currentZoneId,
- currentClassJob,
+ currentZoneId,
gcCurrent,
gcLimsaRank,
gcGridaniaRank,
@@ -328,27 +361,25 @@ namespace FFXIVClassic_Lobby_Server
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.playTime = reader.GetUInt32(21);
+ player.gcCurrent = reader.GetByte(7);
+ player.gcRankLimsa = reader.GetByte(8);
+ player.gcRankGridania = reader.GetByte(9);
+ player.gcRankUldah = reader.GetByte(10);
+ player.currentTitle = reader.GetUInt32(11);
+ player.playerWork.guardian = reader.GetByte(12);
+ player.playerWork.birthdayDay = reader.GetByte(13);
+ player.playerWork.birthdayMonth = reader.GetByte(14);
+ player.playerWork.initialTown = reader.GetByte(15);
+ player.playerWork.tribe = reader.GetByte(16);
+ player.playerWork.restBonusExpRate = reader.GetInt32(18);
+ player.achievementPoints = reader.GetUInt32(19);
+ player.playTime = reader.GetUInt32(20);
}
}
- player.charaWork.parameterSave.state_mainSkillLevel = 50;
/*
- //Get level of our classjob
+ //Get level of our class
//Load appearance
query = @"
SELECT
@@ -367,14 +398,16 @@ namespace FFXIVClassic_Lobby_Server
}
*/
- //Get level of our classjob
+ //Get level of our class
//Load appearance
query = @"
SELECT
hp,
hpMax,
mp,
- mpMax
+ mpMax,
+ mainSkill,
+ mainSkillLevel
FROM characters_parametersave WHERE characterId = @charId";
cmd = new MySqlCommand(query, conn);
@@ -386,7 +419,10 @@ namespace FFXIVClassic_Lobby_Server
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);
+ player.charaWork.parameterSave.mpMax = reader.GetInt16(3);
+
+ player.charaWork.parameterSave.state_mainSkill[0] = reader.GetByte(4);
+ player.charaWork.parameterSave.state_mainSkillLevel = reader.GetUInt16(5);
}
}
diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
index 4cfb757a..db6dbd10 100644
--- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
+++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
@@ -180,6 +180,7 @@
+
diff --git a/FFXIVClassic Map Server/Server.cs b/FFXIVClassic Map Server/Server.cs
index b33904de..6839a823 100644
--- a/FFXIVClassic Map Server/Server.cs
+++ b/FFXIVClassic Map Server/Server.cs
@@ -348,7 +348,7 @@ namespace FFXIVClassic_Lobby_Server
}
}
- public void testCodePacket(uint id, uint value, string target)
+ public void changeProperty(uint id, uint value, string target)
{
SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(target);
@@ -833,7 +833,17 @@ namespace FFXIVClassic_Lobby_Server
else if (split[0].Equals("property"))
{
if (split.Length == 4)
- testCodePacket(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]);
+ {
+ changeProperty(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]);
+ }
+ return true;
+ }
+ else if (split[0].Equals("property2"))
+ {
+ if (split.Length == 4)
+ {
+ changeProperty(Convert.ToUInt32(split[1], 16), Convert.ToUInt32(split[2], 16), split[3]);
+ }
return true;
}
}
diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs
index 12d66122..fc6e9a60 100644
--- a/FFXIVClassic Map Server/actors/chara/player/Player.cs
+++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs
@@ -53,7 +53,13 @@ namespace FFXIVClassic_Map_Server.Actors
public const int TIMER_BEHEST = 16;
public const int TIMER_COMPANYBEHEST = 17;
public const int TIMER_RETURN = 18;
- public const int TIMER_SKIRMISH = 19;
+ public const int TIMER_SKIRMISH = 19;
+
+ public static int[] MAXEXP = {570, 700, 880, 1100, 1500, 1800, 2300, 3200, 4300, 5000, //Level <= 10
+ 5900, 6800, 7700, 8700, 9700, 11000, 12000, 13000, 15000, 16000, //Level <= 20
+ 20000, 22000, 23000, 25000, 27000, 29000, 31000, 33000, 35000, 38000, //Level <= 30
+ 45000, 47000, 50000, 53000, 56000, 59000, 62000, 65000, 68000, 71000, //Level <= 40
+ 74000, 78000, 81000, 85000, 89000, 92000, 96000, 100000, 100000, 110000}; //Level <= 50
//Player Info
public uint[] timers = new uint[20];
@@ -710,11 +716,23 @@ namespace FFXIVClassic_Map_Server.Actors
broadcastPacket(createAppearancePacket(actorId), true);
}
+ public void sendCharaExpInfo()
+ {
+
+ }
+
public InventoryItem[] getGearset(ushort classId)
{
return Database.getEquipment(this, classId);
}
+ public void prepareClassChange(byte classId)
+ {
+ //If new class, init abilties and level
+
+ sendCharaExpInfo();
+ }
+
public void doClassChange(byte classId)
{
//load hotbars
@@ -755,7 +773,7 @@ namespace FFXIVClassic_Map_Server.Actors
foreach (SubPacket packet in packets)
broadcastPacket(packet, true);
- Log.info("Class change request to: " + classId);
+ Database.savePlayerCurrentClass(this);
}
public void graphicChange(int slot, InventoryItem invItem)
@@ -827,6 +845,14 @@ namespace FFXIVClassic_Map_Server.Actors
queuePacket(InventoryEndChangePacket.buildPacket(toBeExamined.actorId, actorId));
}
+ public void sendRequestedInfo(params object[] parameters)
+ {
+ List lParams = LuaUtils.createLuaParamList(parameters);
+ SubPacket spacket = InfoRequestResponsePacket.buildPacket(actorId, actorId, lParams);
+ spacket.debugPrintSubPacket();
+ queuePacket(spacket);
+ }
+
public void runEventFunction(string functionName, params object[] parameters)
{
List lParams = LuaUtils.createLuaParamList(parameters);
diff --git a/FFXIVClassic Map Server/packets/send/SetMusicPacket.cs b/FFXIVClassic Map Server/packets/send/SetMusicPacket.cs
index ff9c6571..d4f8320a 100644
--- a/FFXIVClassic Map Server/packets/send/SetMusicPacket.cs
+++ b/FFXIVClassic Map Server/packets/send/SetMusicPacket.cs
@@ -12,6 +12,13 @@ namespace FFXIVClassic_Map_Server.packets.send
public const ushort OPCODE = 0x000C;
public const uint PACKET_SIZE = 0x28;
+ public const ushort EFFECT_IMMEDIATE = 0x1;
+ public const ushort EFFECT_CROSSFADE = 0x2; //??
+ public const ushort EFFECT_LAYER = 0x3; //??
+ public const ushort EFFECT_FADEIN = 0x4;
+ public const ushort EFFECT_PLAY_NORMAL_CHANNEL = 0x5; //Only works for multi channeled music
+ public const ushort EFFECT_PLAY_BATTLE_CHANNEL = 0x6;
+
public static SubPacket buildPacket(uint playerActorID, ushort musicID, ushort musicTrackMode)
{
ulong combined = (ulong)(musicID | (musicTrackMode << 16));
diff --git a/FFXIVClassic Map Server/packets/send/events/RunEventFunctionPacket.cs b/FFXIVClassic Map Server/packets/send/events/RunEventFunctionPacket.cs
index 6708bcbd..5a9878b3 100644
--- a/FFXIVClassic Map Server/packets/send/events/RunEventFunctionPacket.cs
+++ b/FFXIVClassic Map Server/packets/send/events/RunEventFunctionPacket.cs
@@ -32,43 +32,7 @@ namespace FFXIVClassic_Map_Server.packets.send.events
binWriter.Write(Encoding.ASCII.GetBytes(callFunction), 0, Encoding.ASCII.GetByteCount(callFunction) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(callFunction));
binWriter.Seek(0x49, SeekOrigin.Begin);
- //Write out params
- foreach (LuaParam p in luaParams)
- {
- binWriter.Write((Byte)p.typeID);
- switch (p.typeID)
- {
- case 0x0: //Int32
- binWriter.Write(Utils.swapEndian((Int32)p.value));
- break;
- case 0x1: //Int32
- binWriter.Write(Utils.swapEndian((UInt32)p.value));
- break;
- case 0x2: //Null Termed String
- string svalue = (string)p.value;
- binWriter.Write(Encoding.ASCII.GetBytes(svalue), 0, Encoding.ASCII.GetByteCount(svalue));
- if (svalue[svalue.Length - 1] != '\0')
- binWriter.Write((Byte)0);
- break;
- case 0x3: //Boolean False
- break;
- case 0x4: //Boolean True
- break;
- case 0x5: //Nil
- break;
- case 0x6: //Actor (By Id)
- binWriter.Write(Utils.swapEndian((UInt32)p.value));
- break;
- case 0xC: //Byte
- binWriter.Write((Byte)p.value);
- break;
- case 0x1B: //Short?
- //value = reader.ReadUInt16();
- break;
- }
- }
-
- binWriter.Write((Byte)0xF);
+ LuaUtils.writeLuaParams(binWriter, luaParams);
}
}
diff --git a/FFXIVClassic Map Server/packets/send/player/InfoRequestResponsePacket.cs b/FFXIVClassic Map Server/packets/send/player/InfoRequestResponsePacket.cs
new file mode 100644
index 00000000..c568d661
--- /dev/null
+++ b/FFXIVClassic Map Server/packets/send/player/InfoRequestResponsePacket.cs
@@ -0,0 +1,33 @@
+using FFXIVClassic_Lobby_Server.common;
+using FFXIVClassic_Lobby_Server.packets;
+using FFXIVClassic_Map_Server.lua;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FFXIVClassic_Map_Server.packets.send.player
+{
+ class InfoRequestResponsePacket
+ {
+ public const ushort OPCODE = 0x0133;
+ public const uint PACKET_SIZE = 0xE0;
+
+ public static SubPacket buildPacket(uint playerActorID, uint targetActorID, List luaParams)
+ {
+ byte[] data = new byte[PACKET_SIZE - 0x20];
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ LuaUtils.writeLuaParams(binWriter, luaParams);
+ }
+ }
+
+ return new SubPacket(OPCODE, playerActorID, targetActorID, data);
+ }
+ }
+}