diff --git a/serverdata/chat/default_rooms.sdf b/serverdata/chat/default_rooms.sdf new file mode 100644 index 000000000..a64a55bf0 --- /dev/null +++ b/serverdata/chat/default_rooms.sdf @@ -0,0 +1,25 @@ +Room Title +s s +Galaxy public chat for the whole galaxy, cannot create rooms here +system system messages for this galaxy +Chat public chat for this galaxy, can create rooms here +Imperial Imperial chat for this galaxy +ImperialWarRoom Imperial war room chat for this galaxy +Rebel Rebel chat for this galaxy +RebelWarRoom Rebel war room chat for this galaxy +BountyHunter Bounty Hunter chat for this galaxy +Commando Commando chat for this galaxy +Entertainer Entertainer chat for this galaxy +ForceSensitive Force Sensitive chat for this galaxy +Medic Medic chat for this galaxy +Officer Officer chat for this galaxy +Pilot Pilot chat for this galaxy +Politician Politician chat for this galaxy +Smuggler Smuggler chat for this galaxy +Spy Spy chat for this galaxy +Trader Trader chat for this galaxy +BeastMastery Beast Mastery chat for this galaxy +Auction Auction chat for this galaxy +GuildLeader Guild leader chat for this galaxy +Mayor Mayor chat for this galaxy +Trader Trader chat for this galaxy diff --git a/serverdata/chat/planets.sdf b/serverdata/chat/planets.sdf new file mode 100644 index 000000000..6a7c19935 --- /dev/null +++ b/serverdata/chat/planets.sdf @@ -0,0 +1,14 @@ +Planet +s +corellia +dantooine +dathomir +endor +kashyyyk +lok +mustafar +naboo +rori +tatooine +talus +yavin4 \ No newline at end of file diff --git a/src/resources/client_info/IffNode.java b/src/resources/client_info/IffNode.java index f8afaf133..83e005616 100644 --- a/src/resources/client_info/IffNode.java +++ b/src/resources/client_info/IffNode.java @@ -26,6 +26,7 @@ package resources.client_info; import utilities.ByteUtilities; +import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.Charset; @@ -278,7 +279,12 @@ public class IffNode { isForm = false; int chunkSize = bb.getInt(); chunkData = new byte[chunkSize]; - bb.get(chunkData); + try { + bb.get(chunkData); + } catch (BufferUnderflowException e) { + System.err.println("Couldn't get all the chunk data for size " + chunkSize + " in chunk " + getTag()); + e.printStackTrace(); + } return 4 + chunkData.length; } diff --git a/src/resources/client_info/SWGFile.java b/src/resources/client_info/SWGFile.java index 18899ee3a..ccf822a8b 100644 --- a/src/resources/client_info/SWGFile.java +++ b/src/resources/client_info/SWGFile.java @@ -72,17 +72,45 @@ public class SWGFile { System.err.println("Failed to properly read the bytes in file " + file.getAbsolutePath() + "!"); inputStream.close(); return; + } else { + inputStream.close(); } + // Reading will add bytes to the buffer, so we need to flip it before reading the buffer to IffNode's bb.flip(); master = new IffNode("", true); currentForm = master; - master.populateFromBuffer(bb); + + if (!isValidIff(bb, size)) { + System.err.println("Tried to open a file not in a valid Interchangeable File Format: " + file.getAbsolutePath()); + return; + } + + if (size != master.populateFromBuffer(bb)) { + System.err.println("Size mismatch between population result and channel size: " + file.getAbsolutePath()); + return; + } + type = master.getTag(); fileName = file.getAbsolutePath(); + } - inputStream.close(); + private boolean isValidIff(ByteBuffer buffer, int size) { + buffer.mark(); + + byte[] tag = new byte[4]; + buffer.get(tag); + String root = new String(tag); + if (!root.equals("FORM")) + return false; + + int formSize = buffer.getInt(); + if (size != (formSize) + 8) + return false; + + buffer.reset(); + return true; } public IffNode addForm(String tag) { diff --git a/src/resources/client_info/visitors/DatatableData.java b/src/resources/client_info/visitors/DatatableData.java index c856a3b36..859163c83 100644 --- a/src/resources/client_info/visitors/DatatableData.java +++ b/src/resources/client_info/visitors/DatatableData.java @@ -263,6 +263,12 @@ public class DatatableData extends ClientData { return columnTypes[column]; } + public void handleRows(DatatableRowHandler handler) { + for (int r = 0; r < getRowCount(); r++) { + handler.handleRow(r); + } + } + public void setColumnNames(String[] columnNames) { this.columnNames = columnNames; } @@ -282,4 +288,8 @@ public class DatatableData extends ClientData { } return size; } + + public interface DatatableRowHandler { + void handleRow(int row); + } } diff --git a/src/services/chat/ChatRoomService.java b/src/services/chat/ChatRoomService.java index d99b9f143..816f8db50 100644 --- a/src/services/chat/ChatRoomService.java +++ b/src/services/chat/ChatRoomService.java @@ -50,6 +50,8 @@ import resources.Terrain; import resources.chat.ChatAvatar; import resources.chat.ChatResult; import resources.chat.ChatRoom; +import resources.client_info.ServerFactory; +import resources.client_info.visitors.DatatableData; import resources.control.Intent; import resources.control.Service; import resources.objects.player.PlayerObject; @@ -69,11 +71,6 @@ import java.util.concurrent.ConcurrentHashMap; * @author Waverunner */ public class ChatRoomService extends Service { - // Array of only the valid terrains in relation to zones able to use planetary-based chat - private static final List terrains = Arrays.asList( - Terrain.CORELLIA, Terrain.DANTOOINE, Terrain.DATHOMIR, Terrain.ENDOR, Terrain.KASHYYYK, Terrain.LOK, - Terrain.MUSTAFAR, Terrain.NABOO, Terrain.RORI, Terrain.TATOOINE, Terrain.TALUS, Terrain.YAVIN4 - ); private int maxChatRoomId; private Map roomMap; // Map to keep track of each player's recent message for a room to prevent duplicates from client @@ -269,10 +266,10 @@ public class ChatRoomService extends Service { Terrain terrain = player.getCreatureObject().getLocation().getTerrain(); // Enter the new zone-only chat channels - if (!terrains.contains(terrain)) + String planetPath = "SWG." + player.getGalaxyName() + "." + terrain.getNameCapitalized() + "."; + if (getRoom(planetPath + "Planet") == null) return; - String planetPath = "SWG." + player.getGalaxyName() + "." + terrain.getNameCapitalized() + "."; enterChatChannel(player, planetPath + "Planet"); enterChatChannel(player, planetPath + "system"); } @@ -444,31 +441,11 @@ public class ChatRoomService extends Service { */ ChatAvatar systemAvatar = ChatAvatar.getSystemAvatar(galaxy); - // TODO: Move to server datatable file (SDF): Room (s) | Title (s) String basePath = "SWG." + galaxy + "."; - createRoom(systemAvatar, true, basePath + "Galaxy", "public chat for the whole galaxy, cannot create rooms here"); - createRoom(systemAvatar, true, basePath + "system", "system messages for this galaxy"); - createRoom(systemAvatar, true, basePath + "Chat", "public chat for this galaxy, can create rooms here"); - createRoom(systemAvatar, true, basePath + "Imperial", "Imperial chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "ImperialWarRoom", "Imperial war room chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Rebel", "Rebel chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "RebelWarRoom", "Rebel war room chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "BountyHunter", "Bounty Hunter chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Commando", "Commando chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Entertainer", "Entertainer chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "ForceSensitive", "Force Sensitive chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Medic", "Medic chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Officer", "Officer chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Pilot", "Pilot chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Politician", "Politician chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Smuggler", "Smuggler chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Spy", "Spy chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Trader", "Trader chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "BeastMastery", "Beast Mastery chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Auction", "Auction chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "GuildLeader", "Guild leader chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Mayor", "Mayor chat for this galaxy"); - createRoom(systemAvatar, true, basePath + "Trader", "Trader chat for this galaxy"); + + DatatableData rooms = ServerFactory.getDatatable("chat/default_rooms.iff"); + rooms.handleRows((r) -> createRoom(systemAvatar, true, basePath + rooms.getCell(r, 0), (String) rooms.getCell(r, 1))); + createPlanetChannels(systemAvatar, basePath); /* @@ -481,13 +458,13 @@ public class ChatRoomService extends Service { } private void createPlanetChannels(ChatAvatar systemAvatar, String basePath) { - // TODO: Move planets to a server datatable file (SDF): Planet (s) - for (Terrain terrain : terrains) { - String path = basePath + terrain.getNameCapitalized() + "."; + DatatableData planets = ServerFactory.getDatatable("chat/planets.iff"); + planets.handleRows((r) -> { + String path = basePath + planets.getCell(r, 0) + "."; createRoom(systemAvatar, true, path + "Planet", "public chat for this planet, cannot create rooms here"); createRoom(systemAvatar, true, path + "system", "system messages for this planet, cannot create rooms here"); createRoom(systemAvatar, true, path + "Chat", "public chat for this planet, can create rooms here"); - } + }); } private boolean incrementMessageCounter(long networkId, int roomId, int messageId) {