forked from MagicBane/Server
				
			
				 49 changed files with 1468 additions and 1835 deletions
			
			
		| @ -0,0 +1,73 @@@@ -0,0 +1,73 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.Building; | ||||
| import engine.objects.Portal; | ||||
| import engine.objects.Resists; | ||||
| 
 | ||||
| import java.sql.Array; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class dbRunegateHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbRunegateHandler() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public ArrayList<Integer> GET_RUNEGATE_LIST() { | ||||
| 
 | ||||
|         ArrayList<Integer> gateList = new ArrayList<>(); | ||||
| 
 | ||||
|         prepareCallable("SELECT DISTINCT `sourceBuilding` FROM `static_runegate_portals`;"); | ||||
| 
 | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
|             while (rs.next()) { | ||||
|                 gateList.add(rs.getInt("sourceBuilding")); | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return gateList; | ||||
|     } | ||||
| 
 | ||||
|     public ArrayList<Portal> GET_PORTAL_LIST(int gateUID) { | ||||
| 
 | ||||
|         ArrayList<Portal> portalList = new ArrayList<>(); | ||||
|         Building sourceBuilding = (Building) DbManager.getObject(Enum.GameObjectType.Building, gateUID); | ||||
| 
 | ||||
|         prepareCallable("SELECT * FROM `static_runegate_portals` WHERE `sourceBuilding` = ?;"); | ||||
|         setInt(1, gateUID); | ||||
| 
 | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
|                 int targetBuildingID = rs.getInt("targetBuilding"); | ||||
|                 Building targetBuilding = (Building) DbManager.getObject(Enum.GameObjectType.Building, targetBuildingID); | ||||
|                 Enum.PortalType portalType = Enum.PortalType.valueOf(rs.getString("portalType")); | ||||
|                 Portal portal = new Portal(sourceBuilding, portalType, targetBuilding); | ||||
|                 portalList.add(portal); | ||||
|             } | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return portalList; | ||||
|     } | ||||
| } | ||||
| @ -1,98 +0,0 @@@@ -1,98 +0,0 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.server.MBServerStatics; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * @author Murray | ||||
|  * | ||||
|  */ | ||||
| public class SetRateCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public SetRateCmd() { | ||||
|         super("setrate"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pc, String[] args, AbstractGameObject target) { | ||||
| 
 | ||||
| 		if (args.length != 2) { | ||||
| 			this.sendUsage(pc); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		float mod = 0f; | ||||
| 
 | ||||
| 		try { | ||||
| 			mod = Float.parseFloat(args[1]); | ||||
| 		} catch (NumberFormatException e) { | ||||
| 			throwbackError(pc, "Supplied data failed to parse to Float."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 		if (args[0].equals("exp")){ | ||||
| 
 | ||||
| 			MBServerStatics.EXP_RATE_MOD = mod; | ||||
| 			throwbackInfo(pc, "Experience Rate set to: " + mod); | ||||
| 
 | ||||
| 		} else if (args[0].equals("gold")){ | ||||
| 
 | ||||
| 			MBServerStatics.GOLD_RATE_MOD = mod; | ||||
| 			throwbackInfo(pc, "Gold Rate set to: " + mod); | ||||
| 
 | ||||
| 		} else if (args[0].equals("drop")){ | ||||
| 
 | ||||
| 			MBServerStatics.DROP_RATE_MOD = mod; | ||||
| 			throwbackInfo(pc, "Drop Multiplier Rate set to: " + mod); | ||||
| 
 | ||||
| 		} else if (args[0].equals("hotexp")){ | ||||
| 
 | ||||
| 			MBServerStatics.HOT_EXP_RATE_MOD = mod; | ||||
| 			throwbackInfo(pc, "HOTZONE Experience Rate set to: " + mod); | ||||
| 
 | ||||
| 		} else if (args[0].equals("hotgold")){ | ||||
| 
 | ||||
| 			MBServerStatics.HOT_GOLD_RATE_MOD = mod; | ||||
| 			throwbackInfo(pc, "HOTZONE Gold Rate set to: " + mod); | ||||
| 
 | ||||
| 		} else if (args[0].equals("hotdrop")){ | ||||
| 
 | ||||
| 			MBServerStatics.HOT_DROP_RATE_MOD = mod; | ||||
| 			throwbackInfo(pc, "HOTZONE Drop Multiplier Rate set to: " + mod); | ||||
| 
 | ||||
| 		} else if (args[0].equals("production")){ | ||||
| 
 | ||||
| 			MBServerStatics.PRODUCTION_TIME_MULTIPLIER = mod; | ||||
| 			throwbackInfo(pc, "Production Time Multiplier Rate set to: " + mod); | ||||
| 
 | ||||
| 		} else { | ||||
| 			this.sendUsage(pc); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
|         return "' /setrate {exp|gold|drop|hotexp|hotgold|hotdrop} rate'"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
|         return "Sets the rates for exp, gold or drops. Accepts a float, defaults to 1.0"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,82 @@@@ -0,0 +1,82 @@ | ||||
| package engine.net.client.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.DispatchChannel; | ||||
| import engine.exception.MsgSendException; | ||||
| import engine.gameManager.SessionManager; | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.net.Dispatch; | ||||
| import engine.net.DispatchMessage; | ||||
| import engine.net.client.ClientConnection; | ||||
| import engine.net.client.msg.*; | ||||
| import engine.objects.City; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.session.Session; | ||||
| 
 | ||||
| /* | ||||
|  * @Author: | ||||
|  * @Summary: Processes application protocol message which displays | ||||
|  * the map interface.  (Zones, Cities, Realms, Hot-zones) | ||||
|  */ | ||||
| 
 | ||||
| public class CityDataHandler extends AbstractClientMsgHandler { | ||||
| 
 | ||||
|     public CityDataHandler() { | ||||
|         super(KeepAliveServerClientMsg.class); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { | ||||
| 
 | ||||
|         boolean updateCities = false; | ||||
|         Session playerSession; | ||||
|         PlayerCharacter playerCharacter; | ||||
|         Dispatch dispatch; | ||||
| 
 | ||||
|         playerCharacter = origin.getPlayerCharacter(); | ||||
| 
 | ||||
|         if (playerCharacter == null) | ||||
|             return true; | ||||
| 
 | ||||
|         // Session is needed as param for worldObjectMsg.
 | ||||
| 
 | ||||
|         playerSession = SessionManager.getSession(playerCharacter); | ||||
| 
 | ||||
|         if (playerSession == null) | ||||
|             return true; | ||||
| 
 | ||||
|         // No reason to serialize cities everytime map is
 | ||||
|         // opened.  Wait until something has changed.
 | ||||
|         // This does not work for mines.
 | ||||
| 
 | ||||
|         if (playerCharacter.getTimeStamp("cityUpdate") <= City.lastCityUpdate) { | ||||
|             playerCharacter.setTimeStamp("cityUpdate", System.currentTimeMillis()); | ||||
|             updateCities = true; | ||||
|         } | ||||
| 
 | ||||
|         CityDataMsg cityDataMsg = new CityDataMsg(SessionManager.getSession(playerCharacter), false); | ||||
|         cityDataMsg.updateMines(true); | ||||
|         cityDataMsg.updateCities(updateCities); | ||||
| 
 | ||||
|         dispatch = Dispatch.borrow(playerCharacter, cityDataMsg); | ||||
|         DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); | ||||
| 
 | ||||
|         // If the hotZone has changed then update the client's map accordingly.
 | ||||
| 
 | ||||
|         if (playerCharacter.getTimeStamp("hotzoneupdate") <= ZoneManager.hotZoneLastUpdate.toEpochMilli() && ZoneManager.hotZone != null) { | ||||
|                 HotzoneChangeMsg hotzoneChangeMsg = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID()); | ||||
|                 dispatch = Dispatch.borrow(playerCharacter, hotzoneChangeMsg); | ||||
|                 DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); | ||||
|                 playerCharacter.setTimeStamp("hotzoneupdate", System.currentTimeMillis() - 100); | ||||
|         } | ||||
| 
 | ||||
|         // Serialize the realms for this map
 | ||||
| 
 | ||||
|         WorldRealmMsg worldRealmMsg = new WorldRealmMsg(); | ||||
|         dispatch = Dispatch.borrow(playerCharacter, worldRealmMsg); | ||||
|         DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,274 @@@@ -0,0 +1,274 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.net.client.msg; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.net.AbstractConnection; | ||||
| import engine.net.ByteBufferReader; | ||||
| import engine.net.ByteBufferWriter; | ||||
| import engine.net.Network; | ||||
| import engine.net.client.Protocol; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.City; | ||||
| import engine.objects.Mine; | ||||
| import engine.objects.Runegate; | ||||
| import engine.session.Session; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.nio.ByteBuffer; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class CityDataMsg extends ClientNetMsg { | ||||
| 
 | ||||
|     private Session s; | ||||
|     private final boolean forEnterWorld; | ||||
|     private static ByteBuffer cachedEnterWorld; | ||||
|     private static long cachedExpireTime; | ||||
| 
 | ||||
|     public static final long wdComp = 0xFF00FF0000000003L; | ||||
|     private static final byte ver = 1; | ||||
| 
 | ||||
|     private boolean updateCities = false; | ||||
|     private boolean updateRunegates = false; | ||||
|     private boolean updateMines = false; | ||||
| 
 | ||||
|     /** | ||||
|      * This is the general purpose constructor. | ||||
|      * | ||||
|      * @param s             Session | ||||
|      * @param forEnterWorld boolean flag | ||||
|      */ | ||||
|     public CityDataMsg(Session s, boolean forEnterWorld) { | ||||
|         super(Protocol.CITYDATA); | ||||
|         this.s = s; | ||||
|         this.forEnterWorld = forEnterWorld; | ||||
|     } | ||||
| 
 | ||||
|     public CityDataMsg(boolean updateCities, boolean updateRunegates, boolean updateMines) { | ||||
|         super(Protocol.CITYDATA); | ||||
|         this.s = null; | ||||
|         this.forEnterWorld = false; | ||||
|         this.updateCities = updateCities; | ||||
|         this.updateRunegates = updateRunegates; | ||||
|         this.updateMines = updateMines; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * This constructor is used by NetMsgFactory. It attempts to deserialize the | ||||
|      * ByteBuffer into a message. If a BufferUnderflow occurs (based on reading | ||||
|      * past the limit) then this constructor Throws that Exception to the | ||||
|      * caller. | ||||
|      */ | ||||
|     public CityDataMsg(AbstractConnection origin, ByteBufferReader reader) { | ||||
|         super(Protocol.CITYDATA, origin, reader); | ||||
|         this.forEnterWorld = false; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected int getPowerOfTwoBufferSize() { | ||||
|         return (18); // 2^14 == 16384
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Serializes the subclass specific items to the supplied NetMsgWriter. | ||||
|      */ | ||||
|     @Override | ||||
|     protected void _serialize(ByteBufferWriter writer) { | ||||
|         if (this.forEnterWorld) | ||||
|             serializeForEnterWorld(writer); | ||||
|         else | ||||
|             serializeForMapUpdate(writer); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Specific use serializer | ||||
|      * | ||||
|      * @param writer | ||||
|      */ | ||||
|     private void serializeForMapUpdate(ByteBufferWriter writer) { | ||||
| 
 | ||||
|         //Handle City updates
 | ||||
| 
 | ||||
|         if (this.updateCities) { | ||||
|             writer.put((byte) 0); | ||||
|             ArrayList<City> cityList = new ArrayList<>(); | ||||
|             ConcurrentHashMap<Integer, AbstractGameObject> map = DbManager.getMap(Enum.GameObjectType.City); | ||||
|             if (map != null) { | ||||
|                 for (AbstractGameObject ago : map.values()) | ||||
|                     if (ago.getObjectType().equals(Enum.GameObjectType.City)) | ||||
|                         cityList.add((City) ago); | ||||
| 
 | ||||
|                 writer.putInt(cityList.size()); | ||||
|                 for (City city : cityList) { | ||||
|                     City.serializeForClientMsg(city, writer); | ||||
|                 } | ||||
| 
 | ||||
|             } else { | ||||
|                 Logger.error("missing city map"); | ||||
|                 writer.putInt(0); | ||||
|             } | ||||
|         } else | ||||
|             writer.put((byte) 1); | ||||
| 
 | ||||
| 
 | ||||
|         //Handle Runegate updates
 | ||||
|         if (this.updateRunegates) { | ||||
| 
 | ||||
|             writer.put((byte) 0); | ||||
|             writer.putInt(Runegate._runegates.values().size()); | ||||
| 
 | ||||
|             for (Runegate runegate : Runegate._runegates.values()) { | ||||
|                 runegate._serializeForEnterWorld(writer); | ||||
|             } | ||||
|         } else | ||||
|             writer.put((byte) 1); | ||||
| 
 | ||||
| 
 | ||||
|         //Handle Mine updates
 | ||||
|         try { | ||||
|             if (this.updateMines) { | ||||
|                 ArrayList<Mine> mineList = new ArrayList<>(); | ||||
|                 for (Mine toAdd : Mine.mineMap.keySet()) { | ||||
|                     mineList.add(toAdd); | ||||
|                 } | ||||
| 
 | ||||
|                 writer.putInt(mineList.size()); | ||||
|                 for (Mine mine : mineList) | ||||
|                     Mine.serializeForClientMsg(mine, writer); | ||||
|             } else | ||||
|                 writer.putInt(0); | ||||
|         } catch (Exception e) { | ||||
|             Logger.error(e); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         writer.put((byte) 0); // PAD
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Specific use serializer | ||||
|      * | ||||
|      * @param writer | ||||
|      */ | ||||
|     private void serializeForEnterWorld(ByteBufferWriter writer) { | ||||
|         if (s == null || s.getPlayerCharacter() == null) | ||||
|             return; | ||||
| 
 | ||||
|         long startT = System.currentTimeMillis(); | ||||
| 
 | ||||
|         if (cachedEnterWorld == null) { | ||||
|             // Never before been cached, so init stuff
 | ||||
|             cachedEnterWorld = Network.byteBufferPool.getBuffer(19); | ||||
|             cachedExpireTime = 0L; | ||||
|         } | ||||
| 
 | ||||
|         //Check to see if its time to renew cache.
 | ||||
|         if (cachedExpireTime < System.currentTimeMillis()) { | ||||
|             synchronized (cachedEnterWorld) { | ||||
|                 CityDataMsg.attemptSerializeForEnterWorld(cachedEnterWorld); | ||||
|             } | ||||
|             cachedExpireTime = startT + 60000; | ||||
|         } | ||||
| 
 | ||||
|         writer.putBB(cachedEnterWorld); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static void attemptSerializeForEnterWorld(ByteBuffer bb) { | ||||
|         bb.clear(); | ||||
|         ByteBufferWriter temp = new ByteBufferWriter(bb); | ||||
|         temp.put((byte) 0); // PAD
 | ||||
| 
 | ||||
| 
 | ||||
|         ArrayList<City> cityList = new ArrayList<>(); | ||||
|         ConcurrentHashMap<Integer, AbstractGameObject> map = DbManager.getMap(Enum.GameObjectType.City); | ||||
|         for (AbstractGameObject ago : map.values()) | ||||
| 
 | ||||
|             if (ago.getObjectType().equals(Enum.GameObjectType.City)) | ||||
|                 cityList.add((City) ago); | ||||
| 
 | ||||
|         temp.putInt(cityList.size()); | ||||
| 
 | ||||
|         for (City city : cityList) | ||||
|             City.serializeForClientMsg(city, temp); | ||||
|         temp.put((byte) 0); // PAD
 | ||||
| 
 | ||||
|         // Serialize runegates
 | ||||
| 
 | ||||
|         temp.putInt(Runegate._runegates.values().size()); | ||||
| 
 | ||||
|         for (Runegate runegate : Runegate._runegates.values()) { | ||||
|             runegate._serializeForEnterWorld(temp); | ||||
|         } | ||||
| 
 | ||||
|         ArrayList<Mine> mineList = new ArrayList<>(); | ||||
|         for (Mine toAdd : Mine.mineMap.keySet()) { | ||||
|             mineList.add(toAdd); | ||||
|         } | ||||
| 
 | ||||
|         temp.putInt(mineList.size()); | ||||
|         for (Mine mine : mineList) | ||||
|             Mine.serializeForClientMsg(mine, temp); | ||||
|         temp.put((byte) 0); // PAD
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Deserializes the subclass specific items from the supplied NetMsgReader. | ||||
|      */ | ||||
|     @Override | ||||
|     protected void _deserialize(ByteBufferReader reader) { | ||||
|         // Client only sends 11 bytes.
 | ||||
| 
 | ||||
|         byte type = reader.get(); | ||||
| 
 | ||||
|         if (type == 1) { | ||||
|             reader.get(); | ||||
|             reader.get(); | ||||
|             reader.getInt(); | ||||
| 
 | ||||
|         } else { | ||||
|             reader.get(); | ||||
|             reader.getInt(); | ||||
|             reader.get(); | ||||
|             reader.getInt(); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return the s | ||||
|      */ | ||||
|     public Session getS() { | ||||
|         return s; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return the forEnterWorld | ||||
|      */ | ||||
|     public boolean isForEnterWorld() { | ||||
|         return forEnterWorld; | ||||
|     } | ||||
| 
 | ||||
|     public void updateCities(boolean value) { | ||||
|         this.updateCities = value; | ||||
|     } | ||||
| 
 | ||||
|     public void updateRunegates(boolean value) { | ||||
|         this.updateRunegates = value; | ||||
|     } | ||||
| 
 | ||||
|     public void updateMines(boolean value) { | ||||
|         this.updateMines = value; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -1,282 +0,0 @@@@ -1,282 +0,0 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.net.client.msg; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.RunegateType; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.net.AbstractConnection; | ||||
| import engine.net.ByteBufferReader; | ||||
| import engine.net.ByteBufferWriter; | ||||
| import engine.net.Network; | ||||
| import engine.net.client.Protocol; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.City; | ||||
| import engine.objects.Mine; | ||||
| import engine.objects.Runegate; | ||||
| import engine.session.Session; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.nio.ByteBuffer; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class WorldObjectMsg extends ClientNetMsg { | ||||
| 
 | ||||
| 	private Session s; | ||||
| 	private boolean forEnterWorld; | ||||
| 	private static ByteBuffer cachedEnterWorld; | ||||
| 	private static long cachedExpireTime; | ||||
| 
 | ||||
| 	public static final long wdComp = 0xFF00FF0000000003L; | ||||
| 	private static byte ver = 1; | ||||
| 
 | ||||
| 	private boolean updateCities = false; | ||||
| 	private boolean updateRunegates = false; | ||||
| 	private boolean updateMines = false; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This is the general purpose constructor. | ||||
| 	 * | ||||
| 	 * @param s | ||||
| 	 *            Session | ||||
| 	 * @param forEnterWorld | ||||
| 	 *            boolean flag | ||||
| 	 */ | ||||
| 	public WorldObjectMsg(Session s, boolean forEnterWorld) { | ||||
| 		super(Protocol.CITYDATA); | ||||
| 		this.s = s; | ||||
| 		this.forEnterWorld = forEnterWorld; | ||||
| 	} | ||||
| 
 | ||||
| 	public WorldObjectMsg(boolean updateCities, boolean updateRunegates, boolean updateMines) { | ||||
| 		super(Protocol.CITYDATA); | ||||
| 		this.s = null; | ||||
| 		this.forEnterWorld = false; | ||||
| 		this.updateCities = updateCities; | ||||
| 		this.updateRunegates = updateRunegates; | ||||
| 		this.updateMines = updateMines; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This constructor is used by NetMsgFactory. It attempts to deserialize the | ||||
| 	 * ByteBuffer into a message. If a BufferUnderflow occurs (based on reading | ||||
| 	 * past the limit) then this constructor Throws that Exception to the | ||||
| 	 * caller. | ||||
| 	 */ | ||||
| 	public WorldObjectMsg(AbstractConnection origin, ByteBufferReader reader) | ||||
| 			 { | ||||
| 		super(Protocol.CITYDATA, origin, reader); | ||||
| 		this.forEnterWorld = false; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected int getPowerOfTwoBufferSize() { | ||||
| 		return (18); // 2^14 == 16384
 | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Serializes the subclass specific items to the supplied NetMsgWriter. | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	protected void _serialize(ByteBufferWriter writer) { | ||||
| 		if (this.forEnterWorld) | ||||
| 			serializeForEnterWorld(writer); | ||||
| 		else | ||||
| 			serializeForMapUpdate(writer); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Specific use serializer | ||||
| 	 * | ||||
| 	 * @param writer | ||||
| 	 */ | ||||
| 	private void serializeForMapUpdate(ByteBufferWriter writer) { | ||||
| 
 | ||||
| 		//Handle City updates
 | ||||
| 
 | ||||
| 		if (this.updateCities) { | ||||
| 			writer.put((byte) 0); | ||||
| 			ArrayList<City> cityList = new ArrayList<>(); | ||||
| 			ConcurrentHashMap<Integer, AbstractGameObject> map = DbManager.getMap(Enum.GameObjectType.City); | ||||
| 			if (map != null) { | ||||
| 				for (AbstractGameObject ago : map.values()) | ||||
| 					if (ago.getObjectType().equals(Enum.GameObjectType.City)) | ||||
| 						cityList.add((City)ago); | ||||
| 				 | ||||
| 				writer.putInt(cityList.size()); | ||||
| 				for (City city: cityList){ | ||||
| 					City.serializeForClientMsg(city, writer); | ||||
| 				} | ||||
| 				 | ||||
| 			} else { | ||||
| 				Logger.error("missing city map"); | ||||
| 				writer.putInt(0); | ||||
| 			} | ||||
| 		} else | ||||
| 			writer.put((byte) 1); | ||||
| 
 | ||||
| 
 | ||||
| 		//Handle Runegate updates
 | ||||
| 		if (this.updateRunegates) { | ||||
| 
 | ||||
| 			writer.put((byte) 0); | ||||
| 			writer.putInt(RunegateType.values().length); | ||||
| 
 | ||||
| 			for(RunegateType gateType : engine.Enum.RunegateType.values()) { | ||||
| 
 | ||||
| 				Runegate.getRunegates()[gateType.ordinal()]._serializeForEnterWorld(writer); | ||||
| 			} | ||||
| 		} else | ||||
| 			writer.put((byte) 1); | ||||
| 
 | ||||
| 
 | ||||
| 		//Handle Mine updates
 | ||||
| 		try{ | ||||
| 			if (this.updateMines) { | ||||
| 				ArrayList<Mine> mineList = new ArrayList<>(); | ||||
| 				for (Mine toAdd: Mine.mineMap.keySet()){ | ||||
| 					mineList.add(toAdd); | ||||
| 				} | ||||
| 				 | ||||
| 				writer.putInt(mineList.size()); | ||||
| 				for (Mine mine: mineList) | ||||
| 					Mine.serializeForClientMsg(mine, writer); | ||||
| 			} else | ||||
| 				writer.putInt(0); | ||||
| 		}catch(Exception e){ | ||||
| 			Logger.error(e); | ||||
| 		} | ||||
| 		 | ||||
| 
 | ||||
| 
 | ||||
| 		writer.put((byte) 0); // PAD
 | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Specific use serializer | ||||
| 	 * | ||||
| 	 * @param writer | ||||
| 	 */ | ||||
| 	private void serializeForEnterWorld(ByteBufferWriter writer) { | ||||
| 		if (s == null || s.getPlayerCharacter() == null) | ||||
| 			return; | ||||
| 
 | ||||
| 		long startT = System.currentTimeMillis(); | ||||
| 
 | ||||
| 		if (cachedEnterWorld == null) { | ||||
| 			// Never before been cached, so init stuff
 | ||||
| 			cachedEnterWorld = Network.byteBufferPool.getBuffer(19); | ||||
| 			cachedExpireTime = 0L; | ||||
| 		} | ||||
| 
 | ||||
| 		//Check to see if its time to renew cache.
 | ||||
| 		if (cachedExpireTime < System.currentTimeMillis()) { | ||||
| 			synchronized (cachedEnterWorld) { | ||||
| 				WorldObjectMsg.attemptSerializeForEnterWorld(cachedEnterWorld); | ||||
| 			} | ||||
| 			cachedExpireTime = startT + 60000; | ||||
| 		} | ||||
| 
 | ||||
| 		writer.putBB(cachedEnterWorld); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	private static void attemptSerializeForEnterWorld(ByteBuffer bb) { | ||||
| 		bb.clear(); | ||||
| 		ByteBufferWriter temp = new ByteBufferWriter(bb); | ||||
| 		temp.put((byte) 0); // PAD
 | ||||
| 
 | ||||
| 
 | ||||
| 		ArrayList<City> cityList = new ArrayList<>(); | ||||
| 		ConcurrentHashMap<Integer, AbstractGameObject> map = DbManager.getMap(Enum.GameObjectType.City); | ||||
| 		for (AbstractGameObject ago : map.values()) | ||||
| 
 | ||||
| 			if (ago.getObjectType().equals(Enum.GameObjectType.City)) | ||||
| 				cityList.add((City)ago); | ||||
| 
 | ||||
| 		temp.putInt(cityList.size()); | ||||
| 		 | ||||
| 		for (City city: cityList) | ||||
| 			City.serializeForClientMsg(city, temp); | ||||
| 		temp.put((byte) 0); // PAD
 | ||||
| 
 | ||||
| 		// Serialize runegates
 | ||||
| 
 | ||||
| 		temp.putInt(RunegateType.values().length); | ||||
| 
 | ||||
| 		for(RunegateType gateType : engine.Enum.RunegateType.values()) { | ||||
| 
 | ||||
| 			Runegate.getRunegates()[gateType.ordinal()]._serializeForEnterWorld(temp); | ||||
| 		} | ||||
| 
 | ||||
| 		ArrayList<Mine> mineList = new ArrayList<>(); | ||||
| 		for (Mine toAdd : Mine.mineMap.keySet()){ | ||||
| 			mineList.add(toAdd); | ||||
| 		} | ||||
| 		 | ||||
| 		temp.putInt(mineList.size()); | ||||
| 		for (Mine mine: mineList) | ||||
| 			Mine.serializeForClientMsg(mine, temp); | ||||
| 		temp.put((byte) 0); // PAD
 | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Deserializes the subclass specific items from the supplied NetMsgReader. | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	protected void _deserialize(ByteBufferReader reader) | ||||
| 			 { | ||||
| 		// Client only sends 11 bytes.
 | ||||
| 		 | ||||
| 		byte type = reader.get(); | ||||
| 		 | ||||
| 		if (type == 1){ | ||||
| 			reader.get(); | ||||
| 			reader.get(); | ||||
| 			reader.getInt(); | ||||
| 			 | ||||
| 		}else{ | ||||
| 			reader.get(); | ||||
| 			reader.getInt(); | ||||
| 			reader.get(); | ||||
| 			reader.getInt(); | ||||
| 		} | ||||
| 		    | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @return the s | ||||
| 	 */ | ||||
| 	public Session getS() { | ||||
| 		return s; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @return the forEnterWorld | ||||
| 	 */ | ||||
| 	public boolean isForEnterWorld() { | ||||
| 		return forEnterWorld; | ||||
| 	} | ||||
| 
 | ||||
| 	public void updateCities(boolean value) { | ||||
| 		this.updateCities = value; | ||||
| 	} | ||||
| 
 | ||||
| 	public void updateRunegates(boolean value) { | ||||
| 		this.updateRunegates = value; | ||||
| 	} | ||||
| 
 | ||||
| 	public void updateMines(boolean value) { | ||||
| 		this.updateMines = value; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue