diff --git a/src/main/java/electrosphere/client/interact/ButtonInteraction.java b/src/main/java/electrosphere/client/interact/ButtonInteraction.java index db52bec5..4e6342e6 100644 --- a/src/main/java/electrosphere/client/interact/ButtonInteraction.java +++ b/src/main/java/electrosphere/client/interact/ButtonInteraction.java @@ -16,6 +16,7 @@ import electrosphere.entity.types.common.CommonEntityFlags; import electrosphere.entity.types.common.CommonEntityUtils; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.EntityMessage; +import electrosphere.net.parser.net.message.InventoryMessage; /** * Stores logic for interaction button @@ -66,6 +67,8 @@ public class ButtonInteraction { case InteractionData.ON_INTERACT_INVENTORY: { LoggerInterface.loggerEngine.DEBUG("Interacting with inventory"); InventoryMainWindow.viewInventory(target); + InventoryMainWindow.viewInventory(Globals.playerEntity); + Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestWatchInventoryMessage(Globals.clientSceneWrapper.mapClientToServerId(target.getId()))); } break; default: { throw new Error("Unhandled interaction signal " + interactionData.getOnInteract()); diff --git a/src/main/java/electrosphere/client/ui/menu/WindowUtils.java b/src/main/java/electrosphere/client/ui/menu/WindowUtils.java index 6b98cf1c..2291f281 100644 --- a/src/main/java/electrosphere/client/ui/menu/WindowUtils.java +++ b/src/main/java/electrosphere/client/ui/menu/WindowUtils.java @@ -192,10 +192,18 @@ public class WindowUtils { */ public static void attemptRedrawInventoryWindows(){ //make sure we're client and the player entity exists - if(Globals.RUN_CLIENT && Globals.playerEntity != null){ - if(Globals.elementService.containsWindow(WindowStrings.WINDOW_CHARACTER)){ - //redraw if necessary - WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, InventoryMainWindow.createInventoryWindow(Globals.playerEntity)); + if(Globals.RUN_CLIENT){ + if(Globals.playerEntity != null){ + if(Globals.elementService.containsWindow(WindowStrings.WINDOW_CHARACTER)){ + //redraw if necessary + WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, InventoryMainWindow.createInventoryWindow(Globals.playerEntity)); + } + } + if(Globals.targetContainer != null){ + if(Globals.elementService.containsWindow(WindowStrings.WINDOW_INVENTORY_TARGET)){ + //redraw if necessary + WindowUtils.replaceWindow(WindowStrings.WINDOW_INVENTORY_TARGET, InventoryMainWindow.createInventoryWindow(Globals.targetContainer)); + } } } } diff --git a/src/main/java/electrosphere/client/ui/menu/ingame/InventoryMainWindow.java b/src/main/java/electrosphere/client/ui/menu/ingame/InventoryMainWindow.java index d69ace9a..a5aafb20 100644 --- a/src/main/java/electrosphere/client/ui/menu/ingame/InventoryMainWindow.java +++ b/src/main/java/electrosphere/client/ui/menu/ingame/InventoryMainWindow.java @@ -70,6 +70,7 @@ public class InventoryMainWindow { } } else { if(Globals.elementService.getWindow(WindowStrings.WINDOW_INVENTORY_TARGET) == null){ + Globals.targetContainer = entity; //create window Window mainMenuWindow = InventoryMainWindow.createInventoryWindow(entity); //register @@ -103,6 +104,9 @@ public class InventoryMainWindow { * @return The Window element for the window */ public static Window createInventoryWindow(Entity entity){ + if(entity == null){ + throw new Error("Trying to recreate inventory window with null entity!"); + } Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState()); rVal.setMaxWidth(Globals.WINDOW_WIDTH / 2); rVal.setMarginBottom(MARGIN); @@ -121,6 +125,9 @@ public class InventoryMainWindow { rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(windowString), false); Globals.elementService.unregisterWindow(windowString); + if(windowString.equals(WindowStrings.WINDOW_INVENTORY_TARGET)){ + Globals.targetContainer = null; + } if(Globals.cameraHandler.getTrackPlayerEntity()){ Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME); } else { diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index 79a7ebac..eda23ef0 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -93,6 +93,7 @@ public class ControlHandler { WindowStrings.VOXEL_TYPE_SELECTION, WindowStrings.SPAWN_TYPE_SELECTION, WindowStrings.WINDOW_CHARACTER, + WindowStrings.WINDOW_INVENTORY_TARGET, WindowStrings.WINDOW_DEBUG, WindowStrings.WINDOW_MENU_INGAME_MAIN, WindowStrings.WINDOW_MENU_INVENTORY, @@ -348,7 +349,7 @@ public class ControlHandler { private boolean onlyInventoryMenusOpen(){ boolean foundInventory = false; for(String windowId : Globals.elementService.getCurrentWindowIds()){ - if(WindowUtils.isInventoryWindow(windowId) || WindowStrings.WINDOW_MENU_INVENTORY.equals(windowId) || WindowStrings.WINDOW_CHARACTER.equals(windowId)){ + if(WindowUtils.isInventoryWindow(windowId) || WindowStrings.WINDOW_MENU_INVENTORY.equals(windowId) || WindowStrings.WINDOW_CHARACTER.equals(windowId) || WindowStrings.WINDOW_INVENTORY_TARGET.equals(windowId)){ foundInventory = true; } else if(Globals.elementService.getWindow(windowId) instanceof Window == false || ((Window)Globals.elementService.getWindow(windowId)).visible) { return false; diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index a233d0bd..3cbf07b7 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -429,6 +429,7 @@ public class Globals { //drag item state public static Entity draggedItem = null; public static Object dragSourceInventory = null; + public static Entity targetContainer = null; diff --git a/src/main/java/electrosphere/entity/ClientEntityUtils.java b/src/main/java/electrosphere/entity/ClientEntityUtils.java index b90ee531..61236e8d 100644 --- a/src/main/java/electrosphere/entity/ClientEntityUtils.java +++ b/src/main/java/electrosphere/entity/ClientEntityUtils.java @@ -9,7 +9,9 @@ import electrosphere.client.interact.ClientInteractionEngine; import electrosphere.engine.Globals; import electrosphere.entity.state.attach.AttachUtils; import electrosphere.entity.state.hitbox.HitboxCollectionState; +import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.types.collision.CollisionObjUtils; +import electrosphere.entity.types.item.ItemUtils; import electrosphere.renderer.actor.ActorUtils; import electrosphere.renderer.actor.instance.TextureInstancedActor; @@ -63,6 +65,12 @@ public class ClientEntityUtils { actor.free(); } + //is an item in an inventory + if(ItemUtils.getContainingParent(entity) != null){ + InventoryUtils.clientRemoveItemFromInventories(ItemUtils.getContainingParent(entity), entity); + } + + if(Globals.clientSceneWrapper != null){ Globals.clientSceneWrapper.getScene().deregisterEntity(entity); Globals.clientSceneWrapper.deregisterTranslationMapping(entity); diff --git a/src/main/java/electrosphere/entity/ServerEntityUtils.java b/src/main/java/electrosphere/entity/ServerEntityUtils.java index a319b243..cfb4dbcd 100644 --- a/src/main/java/electrosphere/entity/ServerEntityUtils.java +++ b/src/main/java/electrosphere/entity/ServerEntityUtils.java @@ -7,6 +7,8 @@ import org.joml.Vector3d; import electrosphere.engine.Globals; import electrosphere.entity.state.attach.AttachUtils; import electrosphere.entity.state.hitbox.HitboxCollectionState; +import electrosphere.entity.state.inventory.InventoryUtils; +import electrosphere.entity.state.inventory.ServerInventoryState; import electrosphere.entity.state.server.ServerCharacterData; import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.logger.LoggerInterface; @@ -170,6 +172,13 @@ public class ServerEntityUtils { Globals.characterService.removeEntity(ServerCharacterData.getServerCharacterData(entity).getCharacterData()); } + // + //Stop inventory watching + if(InventoryUtils.serverGetInventoryState(entity) != null){ + ServerInventoryState serverInventoryState = InventoryUtils.serverGetInventoryState(entity); + serverInventoryState.destroy(); + } + // //deregister all behavior trees EntityUtils.cleanUpEntity(entity); diff --git a/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java b/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java index 11f2e59d..df91c811 100644 --- a/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java +++ b/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import electrosphere.collision.PhysicsEntityUtils; import electrosphere.data.common.treedata.TreeDataAnimation; @@ -374,6 +375,18 @@ public class ClientEquipState implements BehaviorTree { } } + /** + * Performs the actual logic to turn meshes on/off when unequipping an item + * @param pointId The equipment point to unequip + */ + public void clientTransformUnequip(Entity itemEnt){ + for(Entry pair : this.equipMap.entrySet()){ + if(pair.getValue().equals(itemEnt)){ + this.clientTransformUnequipPoint(pair.getKey()); + } + } + } + /** * Checks if a point has an item equipped * @param point the equip point diff --git a/src/main/java/electrosphere/entity/state/inventory/ClientInventoryState.java b/src/main/java/electrosphere/entity/state/inventory/ClientInventoryState.java index 0f178304..25ea79df 100644 --- a/src/main/java/electrosphere/entity/state/inventory/ClientInventoryState.java +++ b/src/main/java/electrosphere/entity/state/inventory/ClientInventoryState.java @@ -13,6 +13,8 @@ import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.equip.ClientToolbarState; import electrosphere.entity.state.item.ClientChargeState; +import electrosphere.entity.types.item.ItemUtils; +import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.InventoryMessage; import electrosphere.net.server.protocol.InventoryProtocol; @@ -21,14 +23,26 @@ import electrosphere.net.server.protocol.InventoryProtocol; */ public class ClientInventoryState implements BehaviorTree { + /** + * The queue of messages to handle + */ CopyOnWriteArrayList networkMessageQueue = new CopyOnWriteArrayList(); + /** + * Parent entity of this inventory state + */ Entity parent; - ClientInventoryState() { - - } + /** + * Constructor + */ + private ClientInventoryState(){ } + /** + * Creates a client inventory state + * @param parent The parent entity + * @return The client's inventory state + */ public static ClientInventoryState clientCreateInventoryState(Entity parent){ ClientInventoryState rVal = new ClientInventoryState(); rVal.parent = parent; @@ -43,30 +57,39 @@ public class ClientInventoryState implements BehaviorTree { networkMessageQueue.remove(message); switch(message.getMessageSubtype()){ case ADDITEMTOINVENTORY: { - //the ID we get is of the in-inventory item - Entity inInventorySpawnedItem = InventoryUtils.clientConstructInInventoryItem(parent,message.getitemTemplate()); - //map id - if(inInventorySpawnedItem != null){ - Globals.clientSceneWrapper.mapIdToId(inInventorySpawnedItem.getId(), message.getentityId()); + if(Globals.clientSceneWrapper.containsServerId(message.getitemEntId())){ + LoggerInterface.loggerNetworking.WARNING("Client move item " + message.getitemEntId()); + Entity clientSideContainer = Globals.clientSceneWrapper.getEntityFromServerId(message.gettargetEntId()); + Entity clientSideItem = Globals.clientSceneWrapper.getEntityFromServerId(message.getitemEntId()); + ClientInventoryState.moveItem(clientSideContainer, clientSideItem, message.getcontainerType(), message.getequipPointId()); + } else { + LoggerInterface.loggerNetworking.WARNING("Client create item " + message.getitemEntId()); + Entity clientSideContainer = Globals.clientSceneWrapper.getEntityFromServerId(message.gettargetEntId()); + //the ID we get is of the in-inventory item + Entity inInventorySpawnedItem = InventoryUtils.clientConstructInInventoryItem(clientSideContainer,message.getitemTemplate()); + //map id + if(inInventorySpawnedItem != null){ + Globals.clientSceneWrapper.mapIdToId(inInventorySpawnedItem.getId(), message.getitemEntId()); + } } //attempt re-render ui WindowUtils.attemptRedrawInventoryWindows(); } break; case REMOVEITEMFROMINVENTORY: { + LoggerInterface.loggerNetworking.WARNING("Client destroy item " + message.getentityId()); Entity item = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); if(item != null){ InventoryUtils.clientRemoveItemFromInventories(parent, item); //attempt re-render ui WindowUtils.attemptRedrawInventoryWindows(); - //destroy the item - ClientEntityUtils.destroyEntity(item); } } break; case SERVERCOMMANDMOVEITEMCONTAINER: { + LoggerInterface.loggerNetworking.WARNING("Client move item container " + message.getentityId()); //this is a command to switch an item from one inventory to another (ie equip->natural or vice-versa) + Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); switch(message.getcontainerType()){ case InventoryProtocol.INVENTORY_TYPE_EQUIP: { - Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); String equipPointId = message.getequipPointId(); if(InventoryUtils.hasNaturalInventory(parent)){ UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent); @@ -87,7 +110,6 @@ public class ClientInventoryState implements BehaviorTree { } } break; case InventoryProtocol.INVENTORY_TYPE_NATURAL: { - Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); if(InventoryUtils.hasNaturalInventory(parent)){ UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent); naturalInventory.removeItem(target); @@ -107,7 +129,6 @@ public class ClientInventoryState implements BehaviorTree { } } break; case InventoryProtocol.INVENTORY_TYPE_TOOLBAR: { - Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); if(InventoryUtils.hasNaturalInventory(parent)){ UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent); naturalInventory.removeItem(target); @@ -116,7 +137,9 @@ public class ClientInventoryState implements BehaviorTree { RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent); if(ClientEquipState.getClientEquipState(parent) != null){ ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(parent); - clientEquipState.clientTransformUnequipPoint(equipInventory.getItemSlot(target)); + if(equipInventory.containsItem(target)){ + clientEquipState.clientTransformUnequipPoint(equipInventory.getItemSlot(target)); + } } equipInventory.tryRemoveItem(target); } @@ -131,6 +154,7 @@ public class ClientInventoryState implements BehaviorTree { WindowUtils.attemptRedrawInventoryWindows(); } break; case SERVERCOMMANDUNEQUIPITEM: { + LoggerInterface.loggerNetworking.WARNING("Client unequip item " + message.getequipPointId()); switch(message.getcontainerType()){ case InventoryProtocol.INVENTORY_TYPE_NATURAL: { throw new UnsupportedOperationException("unsupported!"); @@ -154,6 +178,7 @@ public class ClientInventoryState implements BehaviorTree { } } break; case SERVERCOMMANDEQUIPITEM: { + LoggerInterface.loggerNetworking.WARNING("Client equip item " + message.getentityId()); //translate equipper id Entity equipper = Globals.clientSceneWrapper.getEntityFromServerId(message.getequipperId()); //spawn in world id @@ -187,6 +212,7 @@ public class ClientInventoryState implements BehaviorTree { } } break; case SERVERUPDATEITEMCHARGES: { + LoggerInterface.loggerNetworking.WARNING("Client set item charges " + message.getentityId()); Entity clientInventoryItem = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); ClientChargeState clientChargeState = ClientChargeState.getClientChargeState(clientInventoryItem); clientChargeState.setCharges(message.getcharges()); @@ -199,12 +225,107 @@ public class ClientInventoryState implements BehaviorTree { case CLIENTREQUESTEQUIPITEM: case CLIENTREQUESTUNEQUIPITEM: case CLIENTREQUESTPERFORMITEMACTION: + case CLIENTREQUESTWATCHINVENTORY: + case CLIENTREQUESTUNWATCHINVENTORY: break; } } this.networkMessageQueue.addAll(bouncedMessages); } + /** + * Moves an item into an inventory on a container + * @param containerEnt The container + * @param itemEnt The item + * @param targetContainer The type of container (natural, toolbar, etc) + * @param targetSlot (Optional) The slot within the container + */ + private static void moveItem(Entity containerEnt, Entity itemEnt, int targetContainer, String targetSlot){ + if(ItemUtils.getContainingParent(itemEnt) != null){ + Entity existingContainerEnt = ItemUtils.getContainingParent(itemEnt); + if(InventoryUtils.hasNaturalInventory(existingContainerEnt)){ + UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(existingContainerEnt); + naturalInventory.removeItem(itemEnt); + } + if(InventoryUtils.hasToolbarInventory(existingContainerEnt)){ + RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(existingContainerEnt); + if(ClientToolbarState.hasClientToolbarState(existingContainerEnt)){ + ClientToolbarState toolbarState = ClientToolbarState.getClientToolbarState(existingContainerEnt); + toolbarInventory.getEquipPointFromSlot(toolbarState.getSelectedSlot() + ""); + } + toolbarInventory.tryRemoveItem(itemEnt); + } + if(InventoryUtils.hasEquipInventory(existingContainerEnt)){ + RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(existingContainerEnt); + if(ClientEquipState.hasClientEquipState(existingContainerEnt)){ + ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(existingContainerEnt); + clientEquipState.clientTransformUnequip(itemEnt); + } + equipInventory.tryRemoveItem(itemEnt); + } + } + switch(targetContainer){ + case InventoryProtocol.INVENTORY_TYPE_EQUIP: { + String equipPointId = targetSlot; + if(InventoryUtils.hasNaturalInventory(containerEnt)){ + UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(containerEnt); + naturalInventory.removeItem(itemEnt); + } + if(InventoryUtils.hasEquipInventory(containerEnt)){ + RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(containerEnt); + equipInventory.tryRemoveItem(itemEnt); + equipInventory.addItem(equipPointId, itemEnt); + } + if(ClientEquipState.getClientEquipState(containerEnt) != null){ + ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(containerEnt); + clientEquipState.attemptEquip(itemEnt, clientEquipState.getEquipPoint(equipPointId)); + } + if(InventoryUtils.hasToolbarInventory(containerEnt)){ + RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(containerEnt); + toolbarInventory.tryRemoveItem(itemEnt); + } + } break; + case InventoryProtocol.INVENTORY_TYPE_NATURAL: { + if(InventoryUtils.hasNaturalInventory(containerEnt)){ + UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(containerEnt); + naturalInventory.removeItem(itemEnt); + naturalInventory.addItem(itemEnt); + } + if(InventoryUtils.hasEquipInventory(containerEnt)){ + RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(containerEnt); + if(ClientEquipState.getClientEquipState(containerEnt) != null){ + ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(containerEnt); + clientEquipState.clientTransformUnequipPoint(equipInventory.getItemSlot(itemEnt)); + } + equipInventory.tryRemoveItem(itemEnt); + } + if(InventoryUtils.hasToolbarInventory(containerEnt)){ + RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(containerEnt); + toolbarInventory.tryRemoveItem(itemEnt); + } + } break; + case InventoryProtocol.INVENTORY_TYPE_TOOLBAR: { + if(InventoryUtils.hasNaturalInventory(containerEnt)){ + UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(containerEnt); + naturalInventory.removeItem(itemEnt); + } + if(InventoryUtils.hasEquipInventory(containerEnt)){ + RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(containerEnt); + if(ClientEquipState.getClientEquipState(containerEnt) != null){ + ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(containerEnt); + clientEquipState.clientTransformUnequipPoint(equipInventory.getItemSlot(itemEnt)); + } + equipInventory.tryRemoveItem(itemEnt); + } + if(InventoryUtils.hasToolbarInventory(containerEnt)){ + RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(containerEnt); + toolbarInventory.tryRemoveItem(itemEnt); + toolbarInventory.addItem(targetSlot, itemEnt); + } + } + } + } + public void addNetworkMessage(InventoryMessage networkMessage) { networkMessageQueue.add(networkMessage); } diff --git a/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java b/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java index cd889cc4..10bdbc80 100644 --- a/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java +++ b/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java @@ -180,9 +180,6 @@ public class InventoryUtils { if(item == null){ throw new Error("Null item provided! " + item); } - if(!CreatureUtils.isCreature(creature)){ - throw new Error("Creature is not a creature!"); - } if(!ItemUtils.isItem(item)){ throw new Error("Item is not an item!"); } @@ -245,14 +242,19 @@ public class InventoryUtils { //if we are the server, immediately send required packets ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(item); dataCell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(item.getId())); - //tell player that their item has another charge - if(CreatureUtils.hasControllerPlayerId(creature)){ - //get the player - int controllerPlayerID = CreatureUtils.getControllerPlayerId(creature); - Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID); - //send message - controllerPlayer.addMessage(InventoryMessage.constructserverUpdateItemChargesMessage(foundExisting.getId(), serverChargeState.getCharges())); + + //tell entities watching this inventory that their item has another charge + ServerInventoryState serverInventoryState = InventoryUtils.serverGetInventoryState(creature); + for(Entity watcher : serverInventoryState.getWatchers()){ + if(CreatureUtils.hasControllerPlayerId(watcher)){ + //get the player + int controllerPlayerID = CreatureUtils.getControllerPlayerId(watcher); + Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID); + //send message + controllerPlayer.addMessage(InventoryMessage.constructserverUpdateItemChargesMessage(foundExisting.getId(), serverChargeState.getCharges())); + } } + //alert script engine ServerScriptUtils.fireSignalOnEntity(creature, "itemPickup", item.getId(), foundExisting.getId()); //destroy the item that was left over @@ -270,14 +272,19 @@ public class InventoryUtils { // ServerDataCell dataCell = Globals.dataCellLocationResolver.getDataCellAtPoint(EntityUtils.getPosition(item),item); //broadcast destroy entityq dataCell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(item.getId())); - //tell controlling player that they have an item in their inventory - if(CreatureUtils.hasControllerPlayerId(creature)){ - //get the player - int controllerPlayerID = CreatureUtils.getControllerPlayerId(creature); - Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID); - //send message - controllerPlayer.addMessage(InventoryMessage.constructaddItemToInventoryMessage(inventoryItem.getId(), ItemUtils.getType(inventoryItem))); + + //tell entities watching this inventory that they have an item in their inventory + ServerInventoryState serverInventoryState = InventoryUtils.serverGetInventoryState(creature); + for(Entity watcher : serverInventoryState.getWatchers()){ + if(CreatureUtils.hasControllerPlayerId(watcher)){ + //get the player + int controllerPlayerID = CreatureUtils.getControllerPlayerId(watcher); + Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID); + //send message + controllerPlayer.addMessage(InventoryMessage.constructaddItemToInventoryMessage(creature.getId(), inventoryItem.getId(), ItemUtils.getType(inventoryItem))); + } } + //alert script engine ServerScriptUtils.fireSignalOnEntity(creature, "itemPickup", item.getId(), inventoryItem.getId()); //destroy the item that was left over @@ -329,12 +336,11 @@ public class InventoryUtils { * @return The in-inventory item */ public static Entity serverAddToNatural(Entity creature, Entity item){ - boolean creatureIsCreature = CreatureUtils.isCreature(creature); boolean itemIsItem = ItemUtils.isItem(item); boolean hasInventory = hasNaturalInventory(creature); //check if the item is already in an inventory boolean itemIsInInventory = ItemUtils.itemIsInInventory(item); - if(creatureIsCreature && itemIsItem && hasInventory){ + if(itemIsItem && hasInventory){ //get inventory //for the moment we're just gonna get natural inventory //later we'll need to search through all creature inventories to find the item @@ -342,9 +348,7 @@ public class InventoryUtils { //destroy in-world entity and create in-inventory item //we're doing this so that we're not constantly sending networking messages for invisible entities attached to the player Entity inventoryItem = item; - boolean sendCreatePacket = false; if(!itemIsInInventory){ - sendCreatePacket = true; inventoryItem = ItemUtils.serverRecreateContainerItem(item, creature); ServerEntityUtils.destroyEntity(item); } @@ -362,18 +366,19 @@ public class InventoryUtils { inventory.addItem(inventoryItem); //set item containing parent ItemUtils.setContainingParent(inventoryItem, creature); - //tell controlling player that they have an item in their inventory - if(CreatureUtils.hasControllerPlayerId(creature)){ - //get the player - int controllerPlayerID = CreatureUtils.getControllerPlayerId(creature); - Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID); - //send message - if(sendCreatePacket){ - controllerPlayer.addMessage(InventoryMessage.constructaddItemToInventoryMessage(inventoryItem.getId(), ItemUtils.getType(inventoryItem))); - } else { - controllerPlayer.addMessage(InventoryMessage.constructserverCommandMoveItemContainerMessage(inventoryItem.getId(), InventoryProtocol.INVENTORY_TYPE_NATURAL, "")); + + //tell entities watching this inventory that they have an item in their inventory + ServerInventoryState serverInventoryState = InventoryUtils.serverGetInventoryState(creature); + for(Entity watcher : serverInventoryState.getWatchers()){ + if(CreatureUtils.hasControllerPlayerId(watcher)){ + //get the player + int controllerPlayerID = CreatureUtils.getControllerPlayerId(watcher); + Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID); + //send message + controllerPlayer.addMessage(InventoryMessage.constructaddItemToInventoryMessage(creature.getId(), inventoryItem.getId(), ItemUtils.getType(inventoryItem))); } } + //alert script engine ServerScriptUtils.fireSignalOnEntity(creature, "itemAddToNatural", item.getId(), inventoryItem.getId()); return inventoryItem; @@ -401,7 +406,8 @@ public class InventoryUtils { public static void clientAttemptStoreItem(Entity creature, Entity item){ //tell the server we want to try the transform NetworkMessage requestPickupMessage = InventoryMessage.constructaddItemToInventoryMessage( - Globals.clientSceneWrapper.mapClientToServerId(item.getId()), + Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()), + Globals.clientSceneWrapper.mapClientToServerId(item.getId()), ItemUtils.getType(item) ); Globals.clientConnection.queueOutgoingMessage(requestPickupMessage); @@ -415,9 +421,8 @@ public class InventoryUtils { */ public static Entity clientConstructInInventoryItem(Entity parentContainer, String type){ //sanity checks - boolean creatureIsCreature = CreatureUtils.isCreature(parentContainer); boolean hasInventory = InventoryUtils.hasNaturalInventory(parentContainer); - if(creatureIsCreature && hasInventory){ + if(hasInventory){ //if we pass sanity checks, actually perform transform //get inventory //for the moment we're just gonna get natural inventory @@ -456,13 +461,12 @@ public class InventoryUtils { throw new Error("Provided null item!"); } //verify creature is creature, item is item, inventory exists, and item is in inventory - boolean creatureIsCreature = CreatureUtils.isCreature(creature); boolean itemIsItem = ItemUtils.isItem(item); boolean hasNaturalInventory = hasNaturalInventory(creature); boolean hasEquipInventory = hasEquipInventory(creature); //check if the item is in an inventory boolean itemIsInInventory = ItemUtils.itemIsInInventory(item); - if(creatureIsCreature && itemIsItem && itemIsInInventory){ + if(itemIsItem && itemIsInInventory){ if(hasNaturalInventory){ //get inventory UnrelationalInventoryState inventory = getNaturalInventory(creature); @@ -498,7 +502,22 @@ public class InventoryUtils { //get parent realm Realm realm = Globals.realmManager.getEntityRealm(creature); //find "in front of creature" - Vector3d dropSpot = new Vector3d(EntityUtils.getPosition(creature)).add(CreatureUtils.getFacingVector(creature)); + Vector3d dropSpot = new Vector3d(EntityUtils.getPosition(creature)); + if(CreatureUtils.getFacingVector(creature) != null){ + dropSpot.add(CreatureUtils.getFacingVector(creature)); + } + // + //tell player that the item is no longer in their inventory + ServerInventoryState serverInventoryState = InventoryUtils.serverGetInventoryState(creature); + for(Entity watcher : serverInventoryState.getWatchers()){ + if(CreatureUtils.hasControllerPlayerId(watcher)){ + //get player + int playerId = CreatureUtils.getControllerPlayerId(watcher); + Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId); + //tell the player to destroy the item + controllerPlayer.addMessage(EntityMessage.constructDestroyMessage(item.getId())); + } + } // //compose item into in-world entity Entity inWorldItem = ItemUtils.serverSpawnBasicItem(realm,dropSpot,ItemUtils.getType(item)); @@ -554,9 +573,6 @@ public class InventoryUtils { if(item == null){ throw new Error("Item is null!"); } - if(!CreatureUtils.isCreature(creature)){ - throw new Error("Creature is not a creature!"); - } if(!ItemUtils.isItem(item)){ throw new Error("Item is not an item!"); } @@ -604,9 +620,6 @@ public class InventoryUtils { if(item == null){ throw new Error("Item is null!"); } - if(!CreatureUtils.isCreature(creature)){ - throw new Error("Creature is not a creature!"); - } if(!ItemUtils.isItem(item)){ throw new Error("Item is not an item!"); } @@ -641,12 +654,15 @@ public class InventoryUtils { } // //tell player that the item is no longer in their inventory - if(CreatureUtils.hasControllerPlayerId(creature)){ - //get player - int playerId = CreatureUtils.getControllerPlayerId(creature); - Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId); - //tell the player they don't have the item anymore - controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(item.getId())); + ServerInventoryState serverInventoryState = InventoryUtils.serverGetInventoryState(creature); + for(Entity watcher : serverInventoryState.getWatchers()){ + if(CreatureUtils.hasControllerPlayerId(watcher)){ + //get player + int playerId = CreatureUtils.getControllerPlayerId(watcher); + Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId); + //tell the player they don't have the item anymore + controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(item.getId())); + } } } @@ -701,12 +717,15 @@ public class InventoryUtils { } // //tell player that the item is no longer in their inventory - if(CreatureUtils.hasControllerPlayerId(creature)){ - //get player - int playerId = CreatureUtils.getControllerPlayerId(creature); - Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId); - //tell the player they don't have the item anymore - controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(item.getId())); + ServerInventoryState serverInventoryState = InventoryUtils.serverGetInventoryState(creature); + for(Entity watcher : serverInventoryState.getWatchers()){ + if(CreatureUtils.hasControllerPlayerId(watcher)){ + //get player + int playerId = CreatureUtils.getControllerPlayerId(watcher); + Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId); + //tell the player they don't have the item anymore + controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(item.getId())); + } } ServerEntityUtils.destroyEntity(item); } diff --git a/src/main/java/electrosphere/entity/state/inventory/ServerInventoryState.java b/src/main/java/electrosphere/entity/state/inventory/ServerInventoryState.java index 4f84f285..f29f2cb7 100644 --- a/src/main/java/electrosphere/entity/state/inventory/ServerInventoryState.java +++ b/src/main/java/electrosphere/entity/state/inventory/ServerInventoryState.java @@ -4,13 +4,16 @@ import java.util.LinkedList; import java.util.List; import electrosphere.data.creature.equip.EquipPoint; +import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.equip.ServerEquipState; import electrosphere.entity.state.equip.ServerToolbarState; +import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.InventoryMessage; +import electrosphere.net.server.player.Player; import electrosphere.server.datacell.utils.EntityLookupUtils; import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils; @@ -24,6 +27,16 @@ public class ServerInventoryState implements BehaviorTree { */ List networkMessageQueue = new LinkedList(); + /** + * All entities watching this inventory state + */ + List watchers = new LinkedList(); + + /** + * All entities that the parent is watching + */ + List toWatch = new LinkedList(); + /** * The parent of the state */ @@ -32,7 +45,7 @@ public class ServerInventoryState implements BehaviorTree { /** * Constructor */ - ServerInventoryState() {} + private ServerInventoryState(){ } /** * Creates an inventory state @@ -42,6 +55,7 @@ public class ServerInventoryState implements BehaviorTree { public static ServerInventoryState serverCreateInventoryState(Entity parent){ ServerInventoryState rVal = new ServerInventoryState(); rVal.parent = parent; + rVal.watchers.add(parent); ServerBehaviorTreeUtils.attachBTreeToEntity(parent, rVal); return rVal; } @@ -52,7 +66,7 @@ public class ServerInventoryState implements BehaviorTree { networkMessageQueue.remove(message); switch(message.getMessageSubtype()){ case ADDITEMTOINVENTORY: { - InventoryUtils.serverAttemptStoreItemTransform(parent, EntityLookupUtils.getEntityById(message.getentityId())); + InventoryUtils.serverAttemptStoreItemTransform(parent, EntityLookupUtils.getEntityById(message.getitemEntId())); } break; case REMOVEITEMFROMINVENTORY: { InventoryUtils.serverAttemptEjectItem(parent, EntityLookupUtils.getEntityById(message.getentityId())); @@ -115,6 +129,18 @@ public class ServerInventoryState implements BehaviorTree { InventoryUtils.serverAttemptStoreItemTransform(container, itemEnt, message.getcontainerType(), message.getequipPointId()); } } break; + case CLIENTREQUESTWATCHINVENTORY: { + Entity targetEnt = EntityLookupUtils.getEntityById(message.gettargetEntId()); + if(targetEnt != null){ + this.watch(targetEnt); + } + } break; + case CLIENTREQUESTUNWATCHINVENTORY: { + Entity targetEnt = EntityLookupUtils.getEntityById(message.gettargetEntId()); + if(targetEnt != null){ + this.unwatch(targetEnt); + } + } break; case CLIENTREQUESTCRAFT: case CLIENTREQUESTPERFORMITEMACTION: case SERVERCOMMANDUNEQUIPITEM: @@ -133,5 +159,90 @@ public class ServerInventoryState implements BehaviorTree { public void addNetworkMessage(InventoryMessage networkMessage) { networkMessageQueue.add(networkMessage); } + + /** + * Tries to watch another entity's inventories + * @param target The entity that contains the inventories + */ + public void watch(Entity target){ + if(target == this.parent){ + throw new Error("Trying to watch self!"); + } + if(!this.toWatch.contains(target)){ + this.toWatch.add(target); + if(InventoryUtils.serverGetInventoryState(target) != null){ + ServerInventoryState targetState = InventoryUtils.serverGetInventoryState(target); + if(!targetState.watchers.contains(this.parent)){ + targetState.watchers.add(this.parent); + targetState.sendInventoryState(this.parent); + } + } + } + } + + /** + * Tries to watch another entity's inventories + * @param target The entity that contains the inventories + */ + public void unwatch(Entity target){ + if(target == this.parent){ + throw new Error("Trying to unwatch self!"); + } + if(this.toWatch.contains(target)){ + this.toWatch.remove(target); + } + if(InventoryUtils.serverGetInventoryState(target) != null){ + ServerInventoryState targetState = InventoryUtils.serverGetInventoryState(target); + if(!targetState.watchers.contains(this.parent)){ + targetState.watchers.remove(this.parent); + } + } + } + + /** + * Sets the state of this inventory to a given entity + */ + public void sendInventoryState(Entity playerEntity){ + //don't send if the target doesn't also have a player + if(!CreatureUtils.hasControllerPlayerId(playerEntity)){ + return; + } + int playerId = CreatureUtils.getControllerPlayerId(playerEntity); + Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId); + if(InventoryUtils.hasNaturalInventory(this.parent)){ + UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(this.parent); + for(Entity itemEnt : naturalInventory.getItems()){ + controllerPlayer.addMessage(InventoryMessage.constructaddItemToInventoryMessage(this.parent.getId(), itemEnt.getId(), ItemUtils.getType(itemEnt))); + } + } + } + + /** + * Destroys this entity's inventory state + */ + public void destroy(){ + for(Entity target : this.toWatch){ + if(InventoryUtils.serverGetInventoryState(target) != null){ + ServerInventoryState targetState = InventoryUtils.serverGetInventoryState(target); + targetState.watchers.remove(this.parent); + targetState.toWatch.remove(this.parent); + } + } + for(Entity target : this.watchers){ + if(InventoryUtils.serverGetInventoryState(target) != null){ + ServerInventoryState targetState = InventoryUtils.serverGetInventoryState(target); + targetState.watchers.remove(this.parent); + targetState.toWatch.remove(this.parent); + } + } + } + + /** + * Gets the list of all entities watching this inventory state + * @return the list of all entities watching this inventory state + */ + public List getWatchers(){ + return this.watchers; + } } diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java index 146163f4..1162a446 100644 --- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java +++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java @@ -636,7 +636,7 @@ public class ItemUtils { if(CreatureUtils.hasControllerPlayerId(parent)){ int playerId = CreatureUtils.getControllerPlayerId(parent); Player player = Globals.playerManager.getPlayerFromId(playerId); - player.addMessage(InventoryMessage.constructaddItemToInventoryMessage(rVal.getId(), itemData.getId())); + player.addMessage(InventoryMessage.constructaddItemToInventoryMessage(parent.getId(), rVal.getId(), itemData.getId())); } return rVal; diff --git a/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java b/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java index abaca18e..f05093fd 100644 --- a/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java @@ -74,6 +74,8 @@ public class InventoryProtocol implements ClientProtocolTemplate= TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTWATCHINVENTORY_SIZE){ + return true; + } else { + return false; + } + case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNWATCHINVENTORY: + if(byteBuffer.getRemaining() >= TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNWATCHINVENTORY_SIZE){ + return true; + } else { + return false; + } case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR: if(byteBuffer.getRemaining() >= TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR_SIZE){ return true; @@ -373,17 +387,20 @@ public class InventoryMessage extends NetworkMessage { if(currentStreamLength < 6){ return false; } - int itemTemplateSize = 0; if(currentStreamLength < 10){ return false; + } + int itemTemplateSize = 0; + if(currentStreamLength < 14){ + return false; } else { - temporaryByteQueue.add(byteBuffer.peek(6 + 0)); - temporaryByteQueue.add(byteBuffer.peek(6 + 1)); - temporaryByteQueue.add(byteBuffer.peek(6 + 2)); - temporaryByteQueue.add(byteBuffer.peek(6 + 3)); + temporaryByteQueue.add(byteBuffer.peek(10 + 0)); + temporaryByteQueue.add(byteBuffer.peek(10 + 1)); + temporaryByteQueue.add(byteBuffer.peek(10 + 2)); + temporaryByteQueue.add(byteBuffer.peek(10 + 3)); itemTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } - if(currentStreamLength < 10 + itemTemplateSize){ + if(currentStreamLength < 14 + itemTemplateSize){ return false; } return true; @@ -396,7 +413,8 @@ public class InventoryMessage extends NetworkMessage { InventoryMessage rVal = (InventoryMessage)pool.get(MessageType.INVENTORY_MESSAGE); rVal.messageType = InventoryMessageType.ADDITEMTOINVENTORY; InventoryMessage.stripPacketHeader(byteBuffer); - rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settargetEntId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setitemEntId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -404,9 +422,10 @@ public class InventoryMessage extends NetworkMessage { /** * Constructs a message of type addItemToInventory */ - public static InventoryMessage constructaddItemToInventoryMessage(int entityId,String itemTemplate){ + public static InventoryMessage constructaddItemToInventoryMessage(int targetEntId,int itemEntId,String itemTemplate){ InventoryMessage rVal = new InventoryMessage(InventoryMessageType.ADDITEMTOINVENTORY); - rVal.setentityId(entityId); + rVal.settargetEntId(targetEntId); + rVal.setitemEntId(itemEntId); rVal.setitemTemplate(itemTemplate); rVal.serialize(); return rVal; @@ -761,6 +780,48 @@ public class InventoryMessage extends NetworkMessage { return rVal; } + /** + * Parses a message of type clientRequestWatchInventory + */ + public static InventoryMessage parseclientRequestWatchInventoryMessage(CircularByteBuffer byteBuffer, MessagePool pool){ + InventoryMessage rVal = (InventoryMessage)pool.get(MessageType.INVENTORY_MESSAGE); + rVal.messageType = InventoryMessageType.CLIENTREQUESTWATCHINVENTORY; + InventoryMessage.stripPacketHeader(byteBuffer); + rVal.settargetEntId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + return rVal; + } + + /** + * Constructs a message of type clientRequestWatchInventory + */ + public static InventoryMessage constructclientRequestWatchInventoryMessage(int targetEntId){ + InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTWATCHINVENTORY); + rVal.settargetEntId(targetEntId); + rVal.serialize(); + return rVal; + } + + /** + * Parses a message of type clientRequestUnwatchInventory + */ + public static InventoryMessage parseclientRequestUnwatchInventoryMessage(CircularByteBuffer byteBuffer, MessagePool pool){ + InventoryMessage rVal = (InventoryMessage)pool.get(MessageType.INVENTORY_MESSAGE); + rVal.messageType = InventoryMessageType.CLIENTREQUESTUNWATCHINVENTORY; + InventoryMessage.stripPacketHeader(byteBuffer); + rVal.settargetEntId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + return rVal; + } + + /** + * Constructs a message of type clientRequestUnwatchInventory + */ + public static InventoryMessage constructclientRequestUnwatchInventoryMessage(int targetEntId){ + InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTUNWATCHINVENTORY); + rVal.settargetEntId(targetEntId); + rVal.serialize(); + return rVal; + } + /** * Parses a message of type clientRequestAddToolbar */ @@ -948,22 +1009,26 @@ public class InventoryMessage extends NetworkMessage { byte[] stringBytes; switch(this.messageType){ case ADDITEMTOINVENTORY: - rawBytes = new byte[2+4+4+itemTemplate.length()]; + rawBytes = new byte[2+4+4+4+itemTemplate.length()]; //message header rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY; //entity messaage header rawBytes[1] = TypeBytes.INVENTORY_MESSAGE_TYPE_ADDITEMTOINVENTORY; - intValues = ByteStreamUtils.serializeIntToBytes(entityId); + intValues = ByteStreamUtils.serializeIntToBytes(targetEntId); for(int i = 0; i < 4; i++){ rawBytes[2+i] = intValues[i]; } - intValues = ByteStreamUtils.serializeIntToBytes(itemTemplate.length()); + intValues = ByteStreamUtils.serializeIntToBytes(itemEntId); for(int i = 0; i < 4; i++){ rawBytes[6+i] = intValues[i]; } + intValues = ByteStreamUtils.serializeIntToBytes(itemTemplate.length()); + for(int i = 0; i < 4; i++){ + rawBytes[10+i] = intValues[i]; + } stringBytes = itemTemplate.getBytes(); for(int i = 0; i < itemTemplate.length(); i++){ - rawBytes[10+i] = stringBytes[i]; + rawBytes[14+i] = stringBytes[i]; } break; case REMOVEITEMFROMINVENTORY: @@ -1119,6 +1184,28 @@ public class InventoryMessage extends NetworkMessage { rawBytes[14+equipPointId.length()+i] = intValues[i]; } break; + case CLIENTREQUESTWATCHINVENTORY: + rawBytes = new byte[2+4]; + //message header + rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY; + //entity messaage header + rawBytes[1] = TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTWATCHINVENTORY; + intValues = ByteStreamUtils.serializeIntToBytes(targetEntId); + for(int i = 0; i < 4; i++){ + rawBytes[2+i] = intValues[i]; + } + break; + case CLIENTREQUESTUNWATCHINVENTORY: + rawBytes = new byte[2+4]; + //message header + rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY; + //entity messaage header + rawBytes[1] = TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNWATCHINVENTORY; + intValues = ByteStreamUtils.serializeIntToBytes(targetEntId); + for(int i = 0; i < 4; i++){ + rawBytes[2+i] = intValues[i]; + } + break; case CLIENTREQUESTADDTOOLBAR: rawBytes = new byte[2+4+4]; //message header diff --git a/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java b/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java index 78275540..39f7c8d1 100644 --- a/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java @@ -390,6 +390,16 @@ public abstract class NetworkMessage { rVal = InventoryMessage.parseclientRequestStoreItemMessage(byteBuffer,pool); } break; + case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTWATCHINVENTORY: + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseclientRequestWatchInventoryMessage(byteBuffer,pool); + } + break; + case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNWATCHINVENTORY: + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseclientRequestUnwatchInventoryMessage(byteBuffer,pool); + } + break; case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR: if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ rVal = InventoryMessage.parseclientRequestAddToolbarMessage(byteBuffer,pool); diff --git a/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java b/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java index 08979a2b..629af21a 100644 --- a/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java +++ b/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java @@ -160,16 +160,20 @@ public class TypeBytes { public static final byte INVENTORY_MESSAGE_TYPE_SERVERCOMMANDUNEQUIPITEM = 5; public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM = 6; public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTSTOREITEM = 7; - public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR = 8; - public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL = 9; - public static final byte INVENTORY_MESSAGE_TYPE_CLIENTUPDATETOOLBAR = 10; - public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION = 11; - public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTCRAFT = 12; - public static final byte INVENTORY_MESSAGE_TYPE_SERVERUPDATEITEMCHARGES = 13; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTWATCHINVENTORY = 8; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNWATCHINVENTORY = 9; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR = 10; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL = 11; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTUPDATETOOLBAR = 12; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION = 13; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTCRAFT = 14; + public static final byte INVENTORY_MESSAGE_TYPE_SERVERUPDATEITEMCHARGES = 15; /* Inventory packet sizes */ public static final byte INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY_SIZE = 6; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTWATCHINVENTORY_SIZE = 6; + public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNWATCHINVENTORY_SIZE = 6; public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR_SIZE = 10; public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL_SIZE = 6; public static final byte INVENTORY_MESSAGE_TYPE_CLIENTUPDATETOOLBAR_SIZE = 6; diff --git a/src/main/java/electrosphere/net/server/protocol/InventoryProtocol.java b/src/main/java/electrosphere/net/server/protocol/InventoryProtocol.java index a01e3ee5..42ea9790 100644 --- a/src/main/java/electrosphere/net/server/protocol/InventoryProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/InventoryProtocol.java @@ -101,6 +101,8 @@ public class InventoryProtocol implements ServerProtocolTemplate