Merged in TheManii/ffxiv-classic-server (pull request #7)

Merge ingame_help part 2
This commit is contained in:
Ioncannon 2016-04-10 11:17:37 -04:00
commit de7484a931
11 changed files with 1311 additions and 554 deletions

View File

@ -0,0 +1,776 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Threading;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Lobby_Server.packets;
using System.IO;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.Properties;
namespace FFXIVClassic_Lobby_Server
{
class CommandProcessor
{
private Dictionary<uint, ConnectedPlayer> mConnectedPlayerList;
private static WorldManager mWorldManager = Server.GetWorldManager();
private static Dictionary<uint, Item> gamedataItems = Server.GetGamedataItems();
// For the moment, this is the only predefined item
// TODO: make a list/enum in the future so that items can be given by name, instead of by id
const UInt32 ITEM_GIL = 1000001;
public CommandProcessor(Dictionary<uint, ConnectedPlayer> playerList)
{
mConnectedPlayerList = playerList;
}
public void sendPacket(ConnectedPlayer client, string path)
{
BasePacket packet = new BasePacket(path);
if (client != null)
{
packet.replaceActorID(client.actorID);
client.queuePacket(packet);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
packet.replaceActorID(entry.Value.actorID);
entry.Value.queuePacket(packet);
}
}
}
public void changeProperty(uint id, uint value, string target)
{
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();
entry.Value.queuePacket(packet);
}
}
public void doMusic(ConnectedPlayer client, string music)
{
ushort musicId;
if (music.ToLower().StartsWith("0x"))
musicId = Convert.ToUInt16(music, 16);
else
musicId = Convert.ToUInt16(music);
if (client != null)
client.queuePacket(BasePacket.createPacket(SetMusicPacket.buildPacket(client.actorID, musicId, 1), true, false));
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
BasePacket musicPacket = BasePacket.createPacket(SetMusicPacket.buildPacket(entry.Value.actorID, musicId, 1), true, false);
entry.Value.queuePacket(musicPacket);
}
}
}
/// <summary>
/// Teleports player to a location on a predefined list
/// </summary>
/// <param name="client">The current player</param>
/// <param name="id">Predefined list: &lt;ffxiv_database&gt;\server_zones_spawnlocations</param>
public void doWarp(ConnectedPlayer client, uint id)
{
FFXIVClassic_Map_Server.WorldManager.ZoneEntrance ze = mWorldManager.getZoneEntrance(id);
if (ze == null)
return;
if (client != null)
mWorldManager.DoZoneChange(client.getActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation);
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
mWorldManager.DoZoneChange(entry.Value.getActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation);
}
}
}
public void doWarp(ConnectedPlayer client, uint zoneId, string privateArea, float x, float y, float z, float r)
{
if (mWorldManager.GetZone(zoneId) == null)
{
if (client != null)
client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Zone does not exist or setting isn't valid."), true, false));
Log.error("Zone does not exist or setting isn't valid.");
}
if (client != null)
mWorldManager.DoZoneChange(client.getActor(), zoneId, privateArea, 0x2, x, y, z, r);
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
mWorldManager.DoZoneChange(entry.Value.getActor(), zoneId, privateArea, 0x2, x, y, z, r);
}
}
}
public void printPos(ConnectedPlayer client)
{
if (client != null)
{
Player p = client.getActor();
client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)), true, false));
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
Log.info(String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation));
}
}
}
private void setGraphic(ConnectedPlayer client, uint slot, uint wId, uint eId, uint vId, uint cId)
{
if (client != null)
{
Player p = client.getActor();
p.graphicChange(slot, wId, eId, vId, cId);
p.sendAppearance();
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.graphicChange(slot, wId, eId, vId, cId);
p.sendAppearance();
}
}
}
private void giveItem(ConnectedPlayer client, uint itemId, int quantity)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.NORMAL).addItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.NORMAL).addItem(itemId, quantity);
}
}
}
private void giveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type)
{
if (client != null)
{
Player p = client.getActor();
if (p.getInventory(type) != null)
p.getInventory(type).addItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
if (p.getInventory(type) != null)
p.getInventory(type).addItem(itemId, quantity);
}
}
}
private void removeItem(ConnectedPlayer client, uint itemId, int quantity)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.NORMAL).removeItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.NORMAL).removeItem(itemId, quantity);
}
}
}
private void removeItem(ConnectedPlayer client, uint itemId, int quantity, ushort type)
{
if (client != null)
{
Player p = client.getActor();
if (p.getInventory(type) != null)
p.getInventory(type).removeItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
if (p.getInventory(type) != null)
p.getInventory(type).removeItem(itemId, quantity);
}
}
}
private void giveCurrency(ConnectedPlayer client, uint itemId, int quantity)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.CURRENCY).addItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.CURRENCY).addItem(itemId, quantity);
}
}
}
// TODO: make removeCurrency() remove all quantity of a currency if quantity_to_remove > quantity_in_inventory instead of silently failing
private void removeCurrency(ConnectedPlayer client, uint itemId, int quantity)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.CURRENCY).removeItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.CURRENCY).removeItem(itemId, quantity);
}
}
}
private void giveKeyItem(ConnectedPlayer client, uint itemId)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1);
}
}
}
private void removeKeyItem(ConnectedPlayer client, uint itemId)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.KEYITEMS).removeItem(itemId, 1);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.KEYITEMS).removeItem(itemId, 1);
}
}
}
private void parseWarp(ConnectedPlayer client, string[] split)
{
float x = 0, y = 0, z = 0, r = 0.0f;
uint zoneId = 0;
string privatearea = null;
if (split.Length == 2) // Predefined list
{
// TODO: Handle !warp Playername
#region !warp (predefined list)
try
{
if (split[1].ToLower().StartsWith("0x"))
zoneId = Convert.ToUInt32(split[1], 16);
else
zoneId = Convert.ToUInt32(split[1]);
}
catch{return;}
#endregion
doWarp(client, zoneId);
}
else if (split.Length == 4)
{
#region !warp X Y Z
if (split[1].StartsWith("@"))
{
split[1] = split[1].Replace("@", string.Empty);
if (String.IsNullOrEmpty(split[1]))
split[1] = "0";
try { x = Single.Parse(split[1]) + client.getActor().positionX; }
catch{return;}
split[1] = x.ToString();
}
if (split[2].StartsWith("@"))
{
split[2] = split[2].Replace("@", string.Empty);
if (String.IsNullOrEmpty(split[2]))
split[2] = "0";
try { y = Single.Parse(split[2]) + client.getActor().positionY; }
catch{return;}
split[2] = y.ToString();
}
if (split[3].StartsWith("@"))
{
split[3] = split[3].Replace("@", string.Empty);
if (String.IsNullOrEmpty(split[3]))
split[3] = "0";
try { z = Single.Parse(split[3]) + client.getActor().positionZ; }
catch{return;}
split[3] = z.ToString();
}
try
{
x = Single.Parse(split[1]);
y = Single.Parse(split[2]);
z = Single.Parse(split[3]);
}
catch{return;}
zoneId = client.getActor().zoneId;
r = client.getActor().rotation;
#endregion
sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z));
doWarp(client, zoneId, privatearea, x, y, z, r);
}
else if (split.Length == 5)
{
#region !warp Zone X Y Z
try
{
x = Single.Parse(split[2]);
y = Single.Parse(split[3]);
z = Single.Parse(split[4]);
}
catch{return;}
if (split[1].ToLower().StartsWith("0x"))
{
try { zoneId = Convert.ToUInt32(split[1], 16); }
catch{return;}
}
else
{
try { zoneId = Convert.ToUInt32(split[1]); }
catch{return;}
}
#endregion
sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z));
doWarp(client, zoneId, privatearea, x, y, z, r);
}
else if (split.Length == 6)
{
#region !warp Zone Instance X Y Z
try
{
x = Single.Parse(split[3]);
y = Single.Parse(split[4]);
z = Single.Parse(split[5]);
}
catch{return;}
if (split[1].ToLower().StartsWith("0x"))
{
try { zoneId = Convert.ToUInt32(split[1], 16); }
catch{return;}
}
else
{
try { zoneId = Convert.ToUInt32(split[1]); }
catch{return;}
}
privatearea = split[2];
#endregion
sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z));
doWarp(client, zoneId, privatearea, x, y, z, r);
}
else
return; // catch any invalid warps here
}
/// <summary>
/// We only use the default options for SendMessagePacket.
/// May as well make it less unwieldly to view
/// </summary>
/// <param name="client"></param>
/// <param name="message"></param>
private void sendMessage(ConnectedPlayer client, String message)
{
if (client != null)
client.getActor().queuePacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", message));
}
internal bool doCommand(string input, ConnectedPlayer client)
{
input.Trim();
if (input.StartsWith("!"))
input = input.Substring(1);
String[] split = input.Split(' ');
split = split.Select(temp => temp.ToLower()).ToArray(); // Ignore case on commands
split = split.Where(temp => temp != "").ToArray(); // strips extra whitespace from commands
// Debug
//sendMessage(client, string.Join(",", split));
if (split.Length >= 1)
{
#region !help
if (split[0].Equals("help"))
{
if (split.Length == 1)
{
sendMessage(client, Resources.CPhelp);
}
if (split.Length == 2)
{
if (split[1].Equals("mypos"))
sendMessage(client, Resources.CPmypos);
else if (split[1].Equals("music"))
sendMessage(client, Resources.CPmusic);
else if (split[1].Equals("warp"))
sendMessage(client, Resources.CPwarp);
else if (split[1].Equals("givecurrency"))
sendMessage(client, Resources.CPgivecurrency);
else if (split[1].Equals("giveitem"))
sendMessage(client, Resources.CPgiveitem);
else if (split[1].Equals("givekeyitem"))
sendMessage(client, Resources.CPgivekeyitem);
else if (split[1].Equals("removecurrency"))
sendMessage(client, Resources.CPremovecurrency);
else if (split[1].Equals("removeitem"))
sendMessage(client, Resources.CPremoveitem);
else if (split[1].Equals("removekeyitem"))
sendMessage(client, Resources.CPremovekeyitem);
else if (split[1].Equals("reloaditems"))
sendMessage(client, Resources.CPreloaditems);
else if (split[1].Equals("reloadzones"))
sendMessage(client, Resources.CPreloadzones);
/*
else if (split[1].Equals("property"))
sendMessage(client, Resources.CPproperty);
else if (split[1].Equals("property2"))
sendMessage(client, Resources.CPproperty2);
else if (split[1].Equals("sendpacket"))
sendMessage(client, Resources.CPsendpacket);
else if (split[1].Equals("setgraphic"))
sendMessage(client, Resources.CPsetgraphic);
*/
}
return true;
}
#endregion
#region !mypos
else if (split[0].Equals("mypos"))
{
try
{
printPos(client);
return true;
}
catch (Exception e)
{
Log.error("Could not load packet: " + e);
}
}
#endregion
#region !reloadzones
else if (split[0].Equals("reloadzones"))
{
if (client != null)
{
Log.info(String.Format("Got request to reset zone: {0}", client.getActor().zoneId));
client.getActor().zone.clear();
client.getActor().zone.addActorToZone(client.getActor());
client.getActor().sendInstanceUpdate();
client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Reseting zone {0}...", client.getActor().zoneId)), true, false));
}
mWorldManager.reloadZone(client.getActor().zoneId);
return true;
}
#endregion
#region !reloaditems
else if (split[0].Equals("reloaditems"))
{
Log.info(String.Format("Got request to reload item gamedata"));
sendMessage(client, "Reloading Item Gamedata...");
gamedataItems.Clear();
gamedataItems = Database.getItemGamedata();
Log.info(String.Format("Loaded {0} items.", gamedataItems.Count));
sendMessage(client, String.Format("Loaded {0} items.", gamedataItems.Count));
return true;
}
#endregion
#region !sendpacket
else if (split[0].Equals("sendpacket"))
{
if (split.Length < 2)
return false;
try
{
sendPacket(client, "./packets/" + split[1]);
return true;
}
catch (Exception e)
{
Log.error("Could not load packet: " + e);
}
}
#endregion
#region !graphic
else if (split[0].Equals("graphic"))
{
try
{
if (split.Length == 6)
setGraphic(client, UInt32.Parse(split[1]), UInt32.Parse(split[2]), UInt32.Parse(split[3]), UInt32.Parse(split[4]), UInt32.Parse(split[5]));
return true;
}
catch (Exception e)
{
Log.error("Could not give item.");
}
}
#endregion
#region !giveitem
else if (split[0].Equals("giveitem"))
{
try
{
if (split.Length == 2)
giveItem(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3)
giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
else if (split.Length == 4)
giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3]));
return true;
}
catch (Exception e)
{
Log.error("Could not give item.");
}
}
#endregion
#region !removeitem
else if (split[0].Equals("removeitem"))
{
if (split.Length < 2)
return false;
try
{
if (split.Length == 2)
removeItem(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3)
removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
else if (split.Length == 4)
removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3]));
return true;
}
catch (Exception e)
{
Log.error("Could not remove item.");
}
}
#endregion
#region !givekeyitem
else if (split[0].Equals("givekeyitem"))
{
try
{
if (split.Length == 2)
giveKeyItem(client, UInt32.Parse(split[1]));
}
catch (Exception e)
{
Log.error("Could not give keyitem.");
}
}
#endregion
#region !removekeyitem
else if (split[0].Equals("removekeyitem"))
{
if (split.Length < 2)
return false;
try
{
if (split.Length == 2)
removeKeyItem(client, UInt32.Parse(split[1]));
return true;
}
catch (Exception e)
{
Log.error("Could not remove keyitem.");
}
}
#endregion
#region !givecurrency
else if (split[0].Equals("givecurrency"))
{
try
{
if (split.Length == 2)
giveCurrency(client, ITEM_GIL, Int32.Parse(split[1]));
else if (split.Length == 3)
giveCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
}
catch (Exception e)
{
Log.error("Could not give currency.");
}
}
#endregion
#region !removecurrency
else if (split[0].Equals("removecurrency"))
{
if (split.Length < 2)
return false;
try
{
if (split.Length == 2)
removeCurrency(client, ITEM_GIL, Int32.Parse(split[1]));
else if (split.Length == 3)
removeCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
return true;
}
catch (Exception e)
{
Log.error("Could not remove currency.");
}
}
#endregion
#region !music
else if (split[0].Equals("music"))
{
if (split.Length < 2)
return false;
try
{
doMusic(client, split[1]);
return true;
}
catch (Exception e)
{
Log.error("Could not change music: " + e);
}
}
#endregion
#region !warp
else if (split[0].Equals("warp"))
{
parseWarp(client, split);
return true;
}
#endregion
#region !property
else if (split[0].Equals("property"))
{
if (split.Length == 4)
{
changeProperty(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]);
}
return true;
}
#endregion
#region !property2
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;
}
#endregion
}
return false;
}
}
}

View File

@ -708,7 +708,7 @@ namespace FFXIVClassic_Lobby_Server
player.getInventory(Inventory.NORMAL).initList(getInventory(player, 0, Inventory.NORMAL));
player.getInventory(Inventory.KEYITEMS).initList(getInventory(player, 0, Inventory.KEYITEMS));
player.getInventory(Inventory.CURRANCY).initList(getInventory(player, 0, Inventory.CURRANCY));
player.getInventory(Inventory.CURRENCY).initList(getInventory(player, 0, Inventory.CURRENCY));
player.getInventory(Inventory.BAZAAR).initList(getInventory(player, 0, Inventory.BAZAAR));
player.getInventory(Inventory.MELDREQUEST).initList(getInventory(player, 0, Inventory.MELDREQUEST));
player.getInventory(Inventory.LOOT).initList(getInventory(player, 0, Inventory.LOOT));

View File

@ -79,6 +79,7 @@
<Compile Include="actors\StaticActors.cs" />
<Compile Include="actors\world\WorldMaster.cs" />
<Compile Include="ClientConnection.cs" />
<Compile Include="CommandProcessor.cs" />
<Compile Include="common\Bitfield.cs" />
<Compile Include="common\Blowfish.cs" />
<Compile Include="common\EfficientHashTables.cs" />
@ -250,6 +251,11 @@
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="lua\LuaUtils.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Server.cs" />
<Compile Include="utils\ActorPropertyPacketUtil.cs" />
<Compile Include="utils\CharacterUtils.cs" />
@ -261,7 +267,12 @@
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>xcopy "$(SolutionDir)data" "$(SolutionDir)$(ProjectName)\$(OutDir)" /E /C /D</PostBuildEvent>

View File

@ -39,6 +39,7 @@ namespace FFXIVClassic_Lobby_Server
class PacketProcessor
{
Server mServer;
CommandProcessor cp;
Dictionary<uint, ConnectedPlayer> mPlayers;
List<ClientConnection> mConnections;
@ -47,6 +48,7 @@ namespace FFXIVClassic_Lobby_Server
mPlayers = playerList;
mConnections = connectionList;
mServer = server;
cp = new CommandProcessor(playerList);
}
public void processPacket(ClientConnection client, BasePacket packet)
@ -198,7 +200,7 @@ namespace FFXIVClassic_Lobby_Server
if (chatMessage.message.StartsWith("!"))
{
if (mServer.doCommand(chatMessage.message, player))
if (cp.doCommand(chatMessage.message, player))
continue;
}

View File

@ -68,12 +68,13 @@ namespace FFXIVClassic_Lobby_Server
if (startServer)
{
Server server = new Server();
CommandProcessor cp = new CommandProcessor(server.getConnectedPlayerList());
server.startServer();
while (true)
{
String input = Console.ReadLine();
server.doCommand(input, null);
cp.doCommand(input, null);
}
}

View File

@ -0,0 +1,257 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FFXIVClassic_Map_Server.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FFXIVClassic_Map_Server.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Adds the specified currency to the current player&apos;s inventory
///
///*Syntax: givecurrency &lt;quantity&gt;
/// givecurrency &lt;quantity&gt; &lt;type&gt;
///&lt;type&gt; is the specific type of currency desired, defaults to gil if no type specified.
/// </summary>
public static string CPgivecurrency {
get {
return ResourceManager.GetString("CPgivecurrency", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Adds the specified items to the current player&apos;s inventory
///
///*Syntax: giveitem &lt;item id&gt;
/// giveitem &lt;item id&gt; &lt;quantity&gt;
/// giveitem &lt;item id&gt; &lt;quantity&gt; &lt;type&gt;
///&lt;item id&gt; is the item&apos;s specific id as defined in the server database
///&lt;type&gt; is the type as defined in the server database (defaults to standard item if not specified).
/// </summary>
public static string CPgiveitem {
get {
return ResourceManager.GetString("CPgiveitem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Adds the specified key item to the current player&apos;s inventory
///
///*Syntax: givekeyitem &lt;item id&gt;
///&lt;item id&gt; is the key item&apos;s specific id as defined in the server database.
/// </summary>
public static string CPgivekeyitem {
get {
return ResourceManager.GetString("CPgivekeyitem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use !help(command) for details
///
///Available commands:
///Standard: mypos, music, warp
///Server Administration: givecurrency, giveitem, givekeyitem, removecurrency, removekeyitem, reloaditems, reloadzones.
/// </summary>
public static string CPhelp {
get {
return ResourceManager.GetString("CPhelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Changes the currently playing background music
///
///*Syntax: music &lt;music id&gt;
///&lt;music id&gt; is the key item&apos;s specific id as defined in the server database.
/// </summary>
public static string CPmusic {
get {
return ResourceManager.GetString("CPmusic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Prints out your current location
///
///*Note: The X/Y/Z coordinates do not correspond to the coordinates listed in the in-game map, they are based on the underlying game data.
/// </summary>
public static string CPmypos {
get {
return ResourceManager.GetString("CPmypos", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to *Syntax: property &lt;value 1&gt; &lt;value 2&gt; &lt;value 3&gt;.
/// </summary>
public static string CPproperty {
get {
return ResourceManager.GetString("CPproperty", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to *Syntax: property2 &lt;value 1&gt; &lt;value 2&gt; &lt;value 3&gt;.
/// </summary>
public static string CPproperty2 {
get {
return ResourceManager.GetString("CPproperty2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reloads the current item data from the database.
/// </summary>
public static string CPreloaditems {
get {
return ResourceManager.GetString("CPreloaditems", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reloads the current zone data from the database.
/// </summary>
public static string CPreloadzones {
get {
return ResourceManager.GetString("CPreloadzones", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Removes the specified currency from the current player&apos;s inventory
///
///*Syntax: removecurrency &lt;quantity&gt;
/// removecurrency &lt;quantity&gt; &lt;type&gt;
///&lt;type&gt; is the specific type of currency desired, defaults to gil if no type specified.
/// </summary>
public static string CPremovecurrency {
get {
return ResourceManager.GetString("CPremovecurrency", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Removes the specified items to the current player&apos;s inventory
///
///*Syntax: removeitem &lt;itemid&gt;
/// removeitem &lt;itemid&gt; &lt;quantity&gt;
///&lt;item id&gt; is the item&apos;s specific id as defined in the server database.
/// </summary>
public static string CPremoveitem {
get {
return ResourceManager.GetString("CPremoveitem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Removes the specified key item to the current player&apos;s inventory
///
///*Syntax: removekeyitem &lt;itemid&gt;
///&lt;item id&gt; is the key item&apos;s specific id as defined in the server database.
/// </summary>
public static string CPremovekeyitem {
get {
return ResourceManager.GetString("CPremovekeyitem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Server sends a special packet to the client
///
///*Syntax: sendpacket &lt;path to packet&gt;
///&lt;Path to packet&gt; is the path to the packet, starting in &lt;map server install location&gt;\packet.
/// </summary>
public static string CPsendpacket {
get {
return ResourceManager.GetString("CPsendpacket", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Overrides the currently displayed character equipment in a specific slot
///
///*Note: Similar to Glamours in FFXIV:ARR, the overridden graphics are purely cosmetic, they do not affect the underlying stats of whatever is equipped on that slot
///
///*Syntax: sendpacket &lt;slot&gt; &lt;wid&gt; &lt;eid&gt; &lt;vid&gt; &lt;cid&gt;
///&lt;w/e/v/c id&gt; are as defined in the client game data.
/// </summary>
public static string CPsetgraphic {
get {
return ResourceManager.GetString("CPsetgraphic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Teleports the player to the specified location
///
///*Note: You can teleport relative to your current position by putting a @ in front of a value, cannot be combined with a zone id or instance name
///
///*Syntax: warp &lt;location list&gt;
/// warp &lt;X coordinate&gt; &lt;Y coordinate&gt; &lt;Z coordinate&gt;
/// warp &lt;zone id&gt; &lt;X coordinate&gt; &lt;Y coordinate&gt; &lt;Z coordinate&gt;
/// warp &lt;zone id&gt; &lt;instance&gt; &lt;X coordinate&gt; &lt;Y coordinate&gt; &lt;Z coordinate&gt;
///&lt;location list&gt; is a pre-defined list of locations from the server database
///&lt;zone id&gt; is the [rest of string was truncated]&quot;;.
/// </summary>
public static string CPwarp {
get {
return ResourceManager.GetString("CPwarp", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CPgivecurrency" xml:space="preserve">
<value>Adds the specified currency to the current player's inventory
*Syntax: givecurrency &lt;quantity&gt;
givecurrency &lt;quantity&gt; &lt;type&gt;
&lt;type&gt; is the specific type of currency desired, defaults to gil if no type specified</value>
</data>
<data name="CPgiveitem" xml:space="preserve">
<value>Adds the specified items to the current player's inventory
*Syntax: giveitem &lt;item id&gt;
giveitem &lt;item id&gt; &lt;quantity&gt;
giveitem &lt;item id&gt; &lt;quantity&gt; &lt;type&gt;
&lt;item id&gt; is the item's specific id as defined in the server database
&lt;type&gt; is the type as defined in the server database (defaults to standard item if not specified)</value>
</data>
<data name="CPgivekeyitem" xml:space="preserve">
<value>Adds the specified key item to the current player's inventory
*Syntax: givekeyitem &lt;item id&gt;
&lt;item id&gt; is the key item's specific id as defined in the server database</value>
</data>
<data name="CPhelp" xml:space="preserve">
<value>Use !help(command) for details
Available commands:
Standard: mypos, music, warp
Server Administration: givecurrency, giveitem, givekeyitem, removecurrency, removekeyitem, reloaditems, reloadzones</value>
</data>
<data name="CPmusic" xml:space="preserve">
<value>Changes the currently playing background music
*Syntax: music &lt;music id&gt;
&lt;music id&gt; is the key item's specific id as defined in the server database</value>
</data>
<data name="CPmypos" xml:space="preserve">
<value>Prints out your current location
*Note: The X/Y/Z coordinates do not correspond to the coordinates listed in the in-game map, they are based on the underlying game data</value>
</data>
<data name="CPproperty" xml:space="preserve">
<value>*Syntax: property &lt;value 1&gt; &lt;value 2&gt; &lt;value 3&gt;</value>
</data>
<data name="CPproperty2" xml:space="preserve">
<value>*Syntax: property2 &lt;value 1&gt; &lt;value 2&gt; &lt;value 3&gt;</value>
</data>
<data name="CPreloaditems" xml:space="preserve">
<value>Reloads the current item data from the database</value>
</data>
<data name="CPreloadzones" xml:space="preserve">
<value>Reloads the current zone data from the database</value>
</data>
<data name="CPremovecurrency" xml:space="preserve">
<value>Removes the specified currency from the current player's inventory
*Syntax: removecurrency &lt;quantity&gt;
removecurrency &lt;quantity&gt; &lt;type&gt;
&lt;type&gt; is the specific type of currency desired, defaults to gil if no type specified</value>
</data>
<data name="CPremoveitem" xml:space="preserve">
<value>Removes the specified items to the current player's inventory
*Syntax: removeitem &lt;itemid&gt;
removeitem &lt;itemid&gt; &lt;quantity&gt;
&lt;item id&gt; is the item's specific id as defined in the server database</value>
</data>
<data name="CPremovekeyitem" xml:space="preserve">
<value>Removes the specified key item to the current player's inventory
*Syntax: removekeyitem &lt;itemid&gt;
&lt;item id&gt; is the key item's specific id as defined in the server database</value>
</data>
<data name="CPsendpacket" xml:space="preserve">
<value>Server sends a special packet to the client
*Syntax: sendpacket &lt;path to packet&gt;
&lt;Path to packet&gt; is the path to the packet, starting in &lt;map server install location&gt;\packet</value>
</data>
<data name="CPsetgraphic" xml:space="preserve">
<value>Overrides the currently displayed character equipment in a specific slot
*Note: Similar to Glamours in FFXIV:ARR, the overridden graphics are purely cosmetic, they do not affect the underlying stats of whatever is equipped on that slot
*Syntax: sendpacket &lt;slot&gt; &lt;wid&gt; &lt;eid&gt; &lt;vid&gt; &lt;cid&gt;
&lt;w/e/v/c id&gt; are as defined in the client game data</value>
</data>
<data name="CPwarp" xml:space="preserve">
<value>Teleports the player to the specified location
*Note: You can teleport relative to your current position by putting a @ in front of a value, cannot be combined with a zone id or instance name
*Syntax: warp &lt;location list&gt;
warp &lt;X coordinate&gt; &lt;Y coordinate&gt; &lt;Z coordinate&gt;
warp &lt;zone id&gt; &lt;X coordinate&gt; &lt;Y coordinate&gt; &lt;Z coordinate&gt;
warp &lt;zone id&gt; &lt;instance&gt; &lt;X coordinate&gt; &lt;Y coordinate&gt; &lt;Z coordinate&gt;
&lt;location list&gt; is a pre-defined list of locations from the server database
&lt;zone id&gt; is the zone's id as defined in the server database
&lt;instance&gt; is an instanced copy of the desired zone that's only visible to the current player</value>
</data>
</root>

View File

@ -95,7 +95,8 @@ namespace FFXIVClassic_Lobby_Server
IPEndPoint serverEndPoint = new System.Net.IPEndPoint(IPAddress.Parse(ConfigConstants.OPTIONS_BINDIP), FFXIV_MAP_PORT);
try{
try
{
mServerSocket = new System.Net.Sockets.Socket(serverEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
}
catch (Exception e)
@ -329,528 +330,19 @@ namespace FFXIVClassic_Lobby_Server
#endregion
public void sendPacket(ConnectedPlayer client, string path)
{
BasePacket packet = new BasePacket(path);
if (client != null)
{
packet.replaceActorID(client.actorID);
client.queuePacket(packet);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
packet.replaceActorID(entry.Value.actorID);
entry.Value.queuePacket(packet);
}
}
}
public void changeProperty(uint id, uint value, string target)
{
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();
entry.Value.queuePacket(packet);
}
}
public void doMusic(ConnectedPlayer client, string music)
{
ushort musicId;
if (music.ToLower().StartsWith("0x"))
musicId = Convert.ToUInt16(music, 16);
else
musicId = Convert.ToUInt16(music);
if (client != null)
client.queuePacket(BasePacket.createPacket(SetMusicPacket.buildPacket(client.actorID, musicId, 1), true, false));
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
BasePacket musicPacket = BasePacket.createPacket(SetMusicPacket.buildPacket(entry.Value.actorID, musicId, 1), true, false);
entry.Value.queuePacket(musicPacket);
}
}
}
public void doWarp(ConnectedPlayer client, string entranceId)
{
uint id;
try
{
if (entranceId.ToLower().StartsWith("0x"))
id = Convert.ToUInt32(entranceId, 16);
else
id = Convert.ToUInt32(entranceId);
}
catch(FormatException e)
{return;}
FFXIVClassic_Map_Server.WorldManager.ZoneEntrance ze = mWorldManager.getZoneEntrance(id);
if (ze == null)
return;
if (client != null)
mWorldManager.DoZoneChange(client.getActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, 0.0f);
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
mWorldManager.DoZoneChange(entry.Value.getActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, 0.0f);
}
}
}
public void doWarp(ConnectedPlayer client, string zone, string privateArea, string sx, string sy, string sz)
{
uint zoneId;
float x,y,z;
if (zone.ToLower().StartsWith("0x"))
zoneId = Convert.ToUInt32(zone, 16);
else
zoneId = Convert.ToUInt32(zone);
if (mWorldManager.GetZone(zoneId) == null)
{
if (client != null)
client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Zone does not exist or setting isn't valid."), true, false));
Log.error("Zone does not exist or setting isn't valid.");
}
x = Single.Parse(sx);
y = Single.Parse(sy);
z = Single.Parse(sz);
if (client != null)
mWorldManager.DoZoneChange(client.getActor(), zoneId, privateArea, 0x2, x, y, z, 0.0f);
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
mWorldManager.DoZoneChange(entry.Value.getActor(), zoneId, privateArea, 0x2, x, y, z, 0.0f);
}
}
}
public static WorldManager GetWorldManager()
{
return mWorldManager;
}
public void printPos(ConnectedPlayer client)
public Dictionary<uint, ConnectedPlayer> getConnectedPlayerList()
{
if (client != null)
{
Player p = client.getActor();
client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Position: {1}, {2}, {3}, {4}", p.customDisplayName, p.positionX, p.positionY, p.positionZ, p.rotation)), true, false));
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
Log.info(String.Format("{0} position: {1}, {2}, {3}, {4}", p.customDisplayName, p.positionX, p.positionY, p.positionZ, p.rotation));
}
}
return mConnectedPlayerList;
}
private void setGraphic(ConnectedPlayer client, uint slot, uint wId, uint eId, uint vId, uint cId)
public static Dictionary<uint, Item> GetGamedataItems()
{
if (client != null)
{
Player p = client.getActor();
p.graphicChange(slot, wId, eId, vId, cId);
p.sendAppearance();
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.graphicChange(slot, wId, eId, vId, cId);
p.sendAppearance();
}
}
}
private void giveItem(ConnectedPlayer client, uint itemId, int quantity)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.NORMAL).addItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.NORMAL).addItem(itemId, quantity);
}
}
}
private void giveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type)
{
if (client != null)
{
Player p = client.getActor();
if (p.getInventory(type) != null)
p.getInventory(type).addItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
if (p.getInventory(type) != null)
p.getInventory(type).addItem(itemId, quantity);
}
}
}
private void removeItem(ConnectedPlayer client, uint itemId, int quantity)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.NORMAL).removeItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.NORMAL).removeItem(itemId, quantity);
}
}
}
private void removeItem(ConnectedPlayer client, uint itemId, int quantity, ushort type)
{
if (client != null)
{
Player p = client.getActor();
if (p.getInventory(type) != null)
p.getInventory(type).removeItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
if (p.getInventory(type) != null)
p.getInventory(type).removeItem(itemId, quantity);
}
}
}
private void giveCurrancy(ConnectedPlayer client, uint itemId, int quantity)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.CURRANCY).addItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.CURRANCY).addItem(itemId, quantity);
}
}
}
private void removeCurrancy(ConnectedPlayer client, uint itemId, int quantity)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.CURRANCY).removeItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.CURRANCY).removeItem(itemId, quantity);
}
}
}
private void giveKeyItem(ConnectedPlayer client, uint itemId)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1);
}
}
}
private void removeKeyItem(ConnectedPlayer client, uint itemId)
{
if (client != null)
{
Player p = client.getActor();
p.getInventory(Inventory.KEYITEMS).removeItem(itemId, 1);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.getInventory(Inventory.KEYITEMS).removeItem(itemId, 1);
}
}
}
internal bool doCommand(string input, ConnectedPlayer client)
{
input.Trim();
if (input.StartsWith("!"))
input = input.Substring(1);
String[] split = input.Split(' ');
if (split.Length >= 1)
{
if (split[0].Equals("mypos"))
{
try
{
printPos(client);
return true;
}
catch (Exception e)
{
Log.error("Could not load packet: " + e);
}
}
else if (split[0].Equals("resetzone"))
{
if (client != null)
{
Log.info(String.Format("Got request to reset zone: {0}", client.getActor().zoneId));
client.getActor().zone.clear();
client.getActor().zone.addActorToZone(client.getActor());
client.getActor().sendInstanceUpdate();
client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Resting zone {0}...", client.getActor().zoneId)), true, false));
}
mWorldManager.reloadZone(client.getActor().zoneId);
return true;
}
else if (split[0].Equals("reloaditems"))
{
Log.info(String.Format("Got request to reload item gamedata"));
if (client != null)
client.getActor().queuePacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Reloading Item Gamedata..."));
gamedataItems.Clear();
gamedataItems = Database.getItemGamedata();
Log.info(String.Format("Loaded {0} items.", gamedataItems.Count));
if (client != null)
client.getActor().queuePacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Loaded {0} items.", gamedataItems.Count)));
return true;
}
else if (split[0].Equals("sendpacket"))
{
if (split.Length < 2)
return false;
try
{
sendPacket(client, "./packets/" + split[1]);
return true;
}
catch (Exception e)
{
Log.error("Could not load packet: " + e);
}
}
else if (split[0].Equals("graphic"))
{
try
{
if (split.Length == 6)
setGraphic(client, UInt32.Parse(split[1]), UInt32.Parse(split[2]), UInt32.Parse(split[3]), UInt32.Parse(split[4]), UInt32.Parse(split[5]));
return true;
}
catch (Exception e)
{
Log.error("Could not give item.");
}
}
else if (split[0].Equals("giveitem"))
{
try
{
if (split.Length == 2)
giveItem(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3)
giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
else if (split.Length == 4)
giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3]));
return true;
}
catch (Exception e)
{
Log.error("Could not give item.");
}
}
else if (split[0].Equals("removeitem"))
{
if (split.Length < 2)
return false;
try
{
if (split.Length == 2)
removeItem(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3)
removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
else if (split.Length == 4)
removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3]));
return true;
}
catch (Exception e)
{
Log.error("Could not remove item.");
}
}
else if (split[0].Equals("givekeyitem"))
{
try
{
if (split.Length == 2)
giveKeyItem(client, UInt32.Parse(split[1]));
}
catch (Exception e)
{
Log.error("Could not give keyitem.");
}
}
else if (split[0].Equals("removekeyitem"))
{
if (split.Length < 2)
return false;
try
{
if (split.Length == 2)
removeKeyItem(client, UInt32.Parse(split[1]));
return true;
}
catch (Exception e)
{
Log.error("Could not remove keyitem.");
}
}
else if (split[0].Equals("givecurrancy"))
{
try
{
if (split.Length == 2)
giveCurrancy(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3)
giveCurrancy(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
}
catch (Exception e)
{
Log.error("Could not give currancy.");
}
}
else if (split[0].Equals("removecurrancy"))
{
if (split.Length < 2)
return false;
try
{
if (split.Length == 2)
removeCurrancy(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3)
removeCurrancy(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
return true;
}
catch (Exception e)
{
Log.error("Could not remove currancy.");
}
}
else if (split[0].Equals("music"))
{
if (split.Length < 2)
return false;
try
{
doMusic(client, split[1]);
return true;
}
catch (Exception e)
{
Log.error("Could not change music: " + e);
}
}
else if (split[0].Equals("warp"))
{
if (split.Length == 2)
doWarp(client, split[1]);
else if (split.Length == 5)
doWarp(client, split[1], null, split[2], split[3], split[4]);
else if (split.Length == 6)
doWarp(client, split[1], split[2], split[3], split[4], split[5]);
return true;
}
else if (split[0].Equals("property"))
{
if (split.Length == 4)
{
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;
}
}
return false;
return gamedataItems;
}
}
}

View File

@ -378,7 +378,6 @@ namespace FFXIVClassic_Map_Server
newArea = GetZone(destinationZoneId);
else
newArea = GetZone(destinationZoneId).getPrivateArea(destinationPrivateArea, 0);
//This server does not contain that zoneId
if (newArea == null)
return;

View File

@ -18,7 +18,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public const ushort LOOT = 0x0004; //Max 0xA
public const ushort MELDREQUEST = 0x0005; //Max 0x04
public const ushort BAZAAR = 0x0007; //Max 0x0A
public const ushort CURRANCY = 0x0063; //Max 0x140
public const ushort CURRENCY = 0x0063; //Max 0x140
public const ushort KEYITEMS = 0x0064; //Max 0x500
public const ushort EQUIPMENT = 0x00FE; //Max 0x23
public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23
@ -132,7 +132,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
{
Database.setQuantity(owner, slot, inventoryCode, list[slot].quantity);
if (inventoryCode != CURRANCY && inventoryCode != KEYITEMS)
if (inventoryCode != CURRENCY && inventoryCode != KEYITEMS)
sendInventoryPackets(list[slot]);
}
@ -144,13 +144,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
list.Add(addedItem);
if (inventoryCode != CURRANCY && inventoryCode != KEYITEMS)
if (inventoryCode != CURRENCY && inventoryCode != KEYITEMS)
sendInventoryPackets(addedItem);
quantityCount -= gItem.maxStack;
}
if (inventoryCode == CURRANCY || inventoryCode == KEYITEMS)
if (inventoryCode == CURRENCY || inventoryCode == KEYITEMS)
sendFullInventory();
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));

View File

@ -140,7 +140,7 @@ namespace FFXIVClassic_Map_Server.Actors
inventories[Inventory.NORMAL] = new Inventory(this, MAXSIZE_INVENTORY_NORMAL, Inventory.NORMAL);
inventories[Inventory.KEYITEMS] = new Inventory(this, MAXSIZE_INVENTORY_KEYITEMS, Inventory.KEYITEMS);
inventories[Inventory.CURRANCY] = new Inventory(this, MAXSIZE_INVENTORY_CURRANCY, Inventory.CURRANCY);
inventories[Inventory.CURRENCY] = new Inventory(this, MAXSIZE_INVENTORY_CURRANCY, Inventory.CURRENCY);
inventories[Inventory.MELDREQUEST] = new Inventory(this, MAXSIZE_INVENTORY_MELDREQUEST, Inventory.MELDREQUEST);
inventories[Inventory.BAZAAR] = new Inventory(this, MAXSIZE_INVENTORY_BAZAAR, Inventory.BAZAAR);
inventories[Inventory.LOOT] = new Inventory(this, MAXSIZE_INVENTORY_LOOT, Inventory.LOOT);
@ -500,7 +500,7 @@ namespace FFXIVClassic_Map_Server.Actors
#region Inventory & Equipment
queuePacket(InventoryBeginChangePacket.buildPacket(actorId));
inventories[Inventory.NORMAL].sendFullInventory();
inventories[Inventory.CURRANCY].sendFullInventory();
inventories[Inventory.CURRENCY].sendFullInventory();
inventories[Inventory.KEYITEMS].sendFullInventory();
inventories[Inventory.BAZAAR].sendFullInventory();
inventories[Inventory.MELDREQUEST].sendFullInventory();