diff --git a/Client/Database/DatabaseManager.cs b/Client/Database/DatabaseManager.cs
index 91d854e..a15caf9 100644
--- a/Client/Database/DatabaseManager.cs
+++ b/Client/Database/DatabaseManager.cs
@@ -81,7 +81,7 @@ public DatabaseManager(RyzomClient client)
public DatabaseNodeBranch GetNodePtr() { return _serverDatabase; }
///
- /// Returns the root branch of the database.
+ /// Returns the root branch of the database.
///
public DatabaseNodeBranch GetDb()
{
diff --git a/Client/Database/DatabaseNodeBranch.cs b/Client/Database/DatabaseNodeBranch.cs
index 448e2b9..2b70c7b 100644
--- a/Client/Database/DatabaseNodeBranch.cs
+++ b/Client/Database/DatabaseNodeBranch.cs
@@ -168,9 +168,9 @@ public override bool AddObserver(IPropertyObserver observer, TextId id)
}
// lookup next element from textid in my index => idx
- string str = id.ReadNext();
+ var str = id.ReadNext();
- DatabaseNode pNode = Find(str);
+ var pNode = Find(str);
// Property not found.
if (pNode == null)
{
@@ -284,6 +284,14 @@ internal virtual void AttachChild(DatabaseNode node, string nodeName)
_predictDatabaseNode = node;
}
+ ///
+ /// Get the number of nodes.
+ ///
+ internal uint NodeCount()
+ {
+ return (ushort)_nodes.Count;
+ }
+
///
/// Get a database node. Return null if out of bounds (no warning)
///
diff --git a/Client/Interface/ServerToLocalAutoCopy.cs b/Client/Interface/ServerToLocalAutoCopy.cs
index 37e7d4c..bc66142 100644
--- a/Client/Interface/ServerToLocalAutoCopy.cs
+++ b/Client/Interface/ServerToLocalAutoCopy.cs
@@ -43,7 +43,7 @@ public class ServerToLocalAutoCopy : IDisposable
private List _Nodes = new List();
/// Sorting of Nodes, by Server Node
List _ServerNodeMap = new List();
- /// Sorting of Nodes, by Local Node
+ /// Sorting of Nodes, by Local Node
List _LocalNodeMap = new List();
/// List of nodes to update until next synchonized client-server counter
private List _UpdateList = new List();
@@ -65,7 +65,7 @@ public void Dispose()
// init the AutoCopy
public void Init(string dbPath)
{
- InterfaceManager pIM = _interfaceManger;
+ var pIM = _interfaceManger;
// Get the synchronisation Counter in Server DB
_ServerCounter = _databaseManager.GetDbProp("SERVER:" + dbPath + ":COUNTER", false);
@@ -158,24 +158,24 @@ void OnServerChange(DatabaseNode serverNode)
return;
}
- DatabaseNodeLeaf serverLeaf = (DatabaseNodeLeaf)serverNode;
+ var serverLeaf = (DatabaseNodeLeaf)serverNode;
var pIM = _interfaceManger;
// Add the leaf to the update list. only if not the counter
if (serverLeaf != _ServerCounter)
{
// build the map key
- Node nodeComp = new Node();
- NodeServerComp sc = new NodeServerComp();
+ var nodeComp = new Node();
+ var sc = new NodeServerComp();
nodeComp.ServerNode = serverLeaf;
sc.Node = nodeComp;
// try to find the node associated to this server leaf
- int index = _ServerNodeMap.IndexOf(sc);
+ var index = _ServerNodeMap.IndexOf(sc);
// if found
if (index > 0 || _ServerNodeMap[0].Node.ServerNode == serverLeaf)
{
- Node node = _ServerNodeMap[index].Node;
+ var node = _ServerNodeMap[index].Node;
// if this node is not already inserted
if (!node.InsertedInUpdateList)
{
@@ -190,9 +190,9 @@ void OnServerChange(DatabaseNode serverNode)
if (pIM.localActionCounterSynchronizedWith(_ServerCounter))
{
// update all leaves
- for (int i = 0; i < _UpdateList.Count; i++)
+ for (var i = 0; i < _UpdateList.Count; i++)
{
- Node node = _UpdateList[i];
+ var node = _UpdateList[i];
_LocalUpdating = true;
node.LocalNode.SetValue64(node.ServerNode.GetValue64());
@@ -238,7 +238,7 @@ public override void Update(DatabaseNode node)
}
}
- // A node here is a pair Server<->Local
+ /// A node here is a pair Server<->Local
private class Node
{
public DatabaseNodeLeaf ServerNode;
@@ -253,7 +253,7 @@ public Node()
}
}
- // Struct for comparing nodes, by either Local or Server pointer
+ /// Struct for comparing nodes, by either Local or Server pointer
private class NodeLocalComp : IComparable
{
public Node Node { get; internal set; }
@@ -274,6 +274,29 @@ public int CompareTo([AllowNull] NodeLocalComp other)
}
}
- void BuildRecursLocalLeaves(DatabaseNodeBranch branch, List leaves) { }
+ void BuildRecursLocalLeaves(DatabaseNodeBranch branch, List leaves)
+ {
+ for (ushort i = 0; i < branch.NodeCount(); i++)
+ {
+ var node = branch.GetNode(i);
+ if (node != null)
+ {
+ if (node is DatabaseNodeLeaf leaf)
+ {
+ // just append to list
+ leaves.Add(leaf);
+ }
+ else
+ {
+ // recurs if a branch (should be...)
+ if (node is DatabaseNodeBranch sonBranch)
+ {
+ BuildRecursLocalLeaves(sonBranch, leaves);
+ }
+ }
+ }
+ }
+
+ }
}
}
diff --git a/Client/Inventory/InventoryManager.cs b/Client/Inventory/InventoryManager.cs
index 4259ebf..7a63738 100644
--- a/Client/Inventory/InventoryManager.cs
+++ b/Client/Inventory/InventoryManager.cs
@@ -6,7 +6,9 @@
// Copyright 2010 Winch Gate Property Limited
///////////////////////////////////////////////////////////////////
+using System;
using Client.Database;
+using Client.Stream;
namespace Client.Inventory
{
@@ -19,7 +21,7 @@ namespace Client.Inventory
/// September 2003
public class InventoryManager
{
- private RyzomClient _client;
+ private readonly RyzomClient _client;
const uint MAX_TEMPINV_ENTRIES = 16;
const uint MAX_BAGINV_ENTRIES = 500;
@@ -33,12 +35,51 @@ public class InventoryManager
const uint MAX_PLAYER_INV_ENTRIES = 500;
// db path for the local inventory
- //#define LOCAL_INVENTORY "LOCAL:INVENTORY"
- //#define SERVER_INVENTORY "SERVER:INVENTORY"
+ public const string LOCAL_INVENTORY = "LOCAL:INVENTORY";
+ public const string SERVER_INVENTORY = "SERVER:INVENTORY";
// db path for all the inventories (without the SERVER: prefix)
- public readonly string[] InventoryDBs;
- public readonly uint[] InventoryIndexes;
+ private readonly string[] InventoryDBs = {
+ "INVENTORY:BAG",
+ "INVENTORY:PACK_ANIMAL0",
+ "INVENTORY:PACK_ANIMAL1",
+ "INVENTORY:PACK_ANIMAL2",
+ "INVENTORY:PACK_ANIMAL3",
+ "INVENTORY:TEMP",
+ "EXCHANGE:GIVE",
+ "EXCHANGE:RECEIVE",
+ "TRADING",
+ "INVENTORY:SHARE",
+ "GUILD:INVENTORY",
+ "INVENTORY:ROOM"
+ };
+
+ public enum INVENTORIES : ushort
+ {
+ // TODO : remove handling, merge it with equipement
+ handling = 0,
+ temporary, // 1
+ equipment, // 2
+ bag, // 3
+ pet_animal, // 4 Character can have 5 pack animal
+ pet_animal1 = pet_animal, // for toString => TInventory convertion
+ pet_animal2,
+ pet_animal3,
+ pet_animal4,
+ max_pet_animal, // 8
+ NUM_INVENTORY = max_pet_animal, // 8
+ UNDEFINED = NUM_INVENTORY, // 8
+
+ exchange, // 9 This is not a bug : exchange is a fake inventory
+ exchange_proposition, // 10 and should not count in the number of inventory
+ // same for botChat trading.
+ trading, // 11
+ reward_sharing, // 12 fake inventory, not in database.xml. Used by the item info protocol only
+ guild, // 13 (warning: number stored in guild saved file)
+ player_room, // 14
+ NUM_ALL_INVENTORY // warning: distinct from NUM_INVENTORY
+ }
+
public readonly uint NumInventories = new uint();
// LOCAL INVENTORY
@@ -71,6 +112,9 @@ public class InventoryManager
// Cache to know if bag is locked or not, because of item worn
private bool[] BagItemEquipped = new bool[MAX_BAGINV_ENTRIES];
+ // ***************************************************************************
+ // db path for all the inventories (without the SERVER: prefix)
+
public InventoryManager(RyzomClient client)
{
_client = client;
@@ -110,5 +154,145 @@ internal void SortBag()
{
// TODO
}
+
+ public void equip(in string bagPath, in string invPath)
+ {
+ //if (isSwimming() || isStunned() || isDead() || isRiding())
+ //{
+ // return;
+ //}
+
+ var pIM = _client.GetInterfaceManager();
+
+ if (bagPath.Length == 0 || invPath.Length == 0)
+ {
+ return;
+ }
+
+ // Get inventory and slot
+ var sIndexInBag = bagPath.Substring(bagPath.LastIndexOf(':') + 1, bagPath.Length);
+ ushort.TryParse(sIndexInBag, out var indexInBag);
+
+ var inventory = (ushort)INVENTORIES.UNDEFINED;
+ ushort invSlot = 0xffff;
+
+ if (invPath.StartsWith("LOCAL:INVENTORY:HAND", StringComparison.InvariantCultureIgnoreCase))
+ {
+ inventory = (ushort)INVENTORIES.handling;
+ ushort.TryParse(invPath.Substring(21, invPath.Length), out invSlot);
+ }
+ else if (invPath.StartsWith("LOCAL:INVENTORY:EQUIP", StringComparison.InvariantCultureIgnoreCase))
+ {
+ inventory = (ushort)INVENTORIES.equipment;
+ ushort.TryParse(invPath.Substring(22, invPath.Length), out invSlot);
+ }
+
+ // Hands management : check if we have to unequip left hand because of incompatibility with right hand item
+ var oldRightIndexInBag = _client.GetDatabaseManager().GetDbProp(invPath + ":INDEX_IN_BAG").GetValue16();
+
+ if (inventory == (ushort)INVENTORIES.handling && invSlot == 0)
+ {
+ // TODO DatabaseCtrlSheet pCSLeftHand = CWidgetManager.getInstance().getElementFromId(CTRL_HAND_LEFT) as DatabaseCtrlSheet;
+ object pCSLeftHand = null;
+
+ if (pCSLeftHand == null)
+ {
+ return;
+ }
+
+ // get sheet of left item
+ uint leftSheet = 0;
+ var pNL = _client.GetDatabaseManager().GetDbProp(LOCAL_INVENTORY + ":HAND:1:INDEX_IN_BAG", false);
+
+ if (pNL == null)
+ {
+ return;
+ }
+ if (pNL.GetValue32() > 0)
+ {
+ var pNL2 = _client.GetDatabaseManager().GetDbProp(LOCAL_INVENTORY + ":BAG:" + (pNL.GetValue32() - 1) + ":SHEET", false);
+ if (pNL2 == null)
+ {
+ return;
+ }
+ leftSheet = (uint)pNL2.GetValue32();
+ }
+
+ // get sheet of previous right hand item
+ uint lastRightSheet = 0;
+ if (oldRightIndexInBag > 0)
+ {
+ pNL = _client.GetDatabaseManager().GetDbProp(LOCAL_INVENTORY + ":BAG:" + (oldRightIndexInBag - 1) + ":SHEET", false);
+ if (pNL == null)
+ {
+ return;
+ }
+ lastRightSheet = (uint)pNL.GetValue32();
+ }
+
+ // get sheet of new right hand item
+ uint rightSheet = 0;
+ if (indexInBag + 1 > 0)
+ {
+ pNL = _client.GetDatabaseManager().GetDbProp(LOCAL_INVENTORY + ":BAG:" + (indexInBag) + ":SHEET", false);
+ if (pNL == null)
+ {
+ return;
+ }
+ rightSheet = (uint)pNL.GetValue32();
+ }
+
+ //// TODO If incompatible -> remove
+ //if (!GetInventory().IsLeftHandItemCompatibleWithRightHandItem(leftSheet, rightSheet, lastRightSheet))
+ //{
+ // GetInventory().Unequip(LOCAL_INVENTORY+ ":HAND:1");
+ //}
+ }
+
+ // update the equip DB pointer
+ _client.GetDatabaseManager().GetDbProp(invPath + ":INDEX_IN_BAG").SetValue16((short)(indexInBag + 1));
+
+ //// TODO Yoyo add: when the user equip an item, the action are invalid during some time
+ //if (indexInBag < MAX_BAGINV_ENTRIES)
+ //{
+ // ItemSheet pIS = _client.GetSheetManager().Get(_client.GetSheetIdFactory().SheetId(GetBagItem(indexInBag).getSheetID())) as ItemSheet;
+ // if (pIS != null)
+ // {
+ // PhraseManager pPM = PhraseManager.getInstance();
+ // pPM.setEquipInvalidation(NetMngr.getCurrentServerTick(), pIS.EquipTime);
+ // }
+ //}
+
+ //// TODO Update trade window if any
+ //if ((BotChatPageAll != null) && (BotChatPageAll.Trade != null))
+ //{
+ // BotChatPageAll.Trade.invalidateCoords();
+ //}
+
+ // Send message to the server
+ if (inventory != (short)INVENTORIES.UNDEFINED)
+ {
+ var @out = new BitMemoryStream();
+ const string sMsg = "ITEM:EQUIP";
+
+ if (_client.GetNetworkManager().GetMessageHeaderManager().PushNameToStream(sMsg, @out))
+ {
+ // Fill the message (equipped inventory, equipped inventory slot, bag slot)
+ @out.Serial(ref inventory);
+ @out.Serial(ref invSlot);
+ @out.Serial(ref indexInBag);
+ _client.GetNetworkManager().Push(@out);
+
+ // TODO pIM.IncLocalSyncActionCounter();
+
+ //nlinfo("impulseCallBack : %s %d %d %d sent", sMsg.c_str(), inventory, invSlot, indexInBag);
+ }
+ else
+ {
+ _client.Log.Warn($"Don't know message name {sMsg}");
+ }
+ }
+ }
+
}
}
diff --git a/Client/Sheet/DatabaseCtrlSheet.cs b/Client/Sheet/DatabaseCtrlSheet.cs
new file mode 100644
index 0000000..e5bdace
--- /dev/null
+++ b/Client/Sheet/DatabaseCtrlSheet.cs
@@ -0,0 +1,29 @@
+///////////////////////////////////////////////////////////////////
+// This file contains modified code from 'Ryzom - MMORPG Framework'
+// http://dev.ryzom.com/projects/ryzom/
+// which is released under GNU Affero General Public License.
+// http://www.gnu.org/licenses/
+// Copyright 2010 Winch Gate Property Limited
+///////////////////////////////////////////////////////////////////
+
+namespace Client.Sheet
+{
+ public class DatabaseCtrlSheet
+ {
+ public enum SheetCategory
+ {
+ Item = 0,
+ Pact,
+ Skill,
+ GuildFlag,
+ Mission,
+ Phrase,
+ DontKnow
+ }
+
+ public DatabaseCtrlSheet()
+ {
+
+ }
+ }
+}