diff --git a/src/intents/sui/SuiWindowIntent.java b/src/intents/sui/SuiWindowIntent.java index 357d64587..a3acdbb58 100644 --- a/src/intents/sui/SuiWindowIntent.java +++ b/src/intents/sui/SuiWindowIntent.java @@ -35,22 +35,29 @@ public class SuiWindowIntent extends Intent { public static final String TYPE = "SuiWindowIntent"; private SuiBaseWindow window; + private int windowId; private Player player; private SuiWindowEvent event; - - public SuiWindowIntent(Player player, SuiBaseWindow window, SuiWindowEvent event) { + + public SuiWindowIntent(Player player, SuiBaseWindow window, int windowId, SuiWindowEvent event) { super(TYPE); this.player = player; this.window = window; + this.windowId = windowId; this.event = event; } + public SuiWindowIntent(Player player, SuiBaseWindow window, SuiWindowEvent event) { + this(player, window, -1, event); + } + public SuiBaseWindow getWindow() { return this.window; } + public int getWindowId() { return windowId; } public Player getPlayer() { return this.player; } public SuiWindowEvent getEvent() { return event; } public enum SuiWindowEvent { NEW, - UPDATE; + CLOSE } } diff --git a/src/network/packets/swg/zone/server_ui/SuiForceClosePage.java b/src/network/packets/swg/zone/server_ui/SuiForceClosePage.java new file mode 100644 index 000000000..d459e1457 --- /dev/null +++ b/src/network/packets/swg/zone/server_ui/SuiForceClosePage.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2015 /// Project SWG /// www.projectswg.com + * + * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. + * Our goal is to create an emulator which will provide a server for players to + * continue playing a game similar to the one they used to play. We are basing + * it on the final publish of the game prior to end-game events. + * + * This file is part of Holocore. + * + * -------------------------------------------------------------------------------- + * + * Holocore is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * Holocore is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Holocore. If not, see + ******************************************************************************/ + +package network.packets.swg.zone.server_ui; + +import network.packets.swg.SWGPacket; + +import java.nio.ByteBuffer; + +/** + * Created by Waverunner on 8/17/2015 + */ +public class SuiForceClosePage extends SWGPacket { + public static final int CRC = getCrc("SuiForceClosePage"); + + private int windowId; + + public SuiForceClosePage(int windowId) { + this.windowId = windowId; + } + + public SuiForceClosePage() {} + + @Override + public void decode(ByteBuffer data) { + if (!super.decode(data, CRC)) + return; + windowId = getInt(data); + } + + @Override + public ByteBuffer encode() { + ByteBuffer bb = ByteBuffer.allocate(10); + addShort(bb, 1); + addInt(bb, CRC); + addInt(bb, windowId); + return bb; + } + + public int getWindowId() { + return windowId; + } +} diff --git a/src/services/sui/SuiService.java b/src/services/sui/SuiService.java index 5b923986e..0a17fe0ff 100644 --- a/src/services/sui/SuiService.java +++ b/src/services/sui/SuiService.java @@ -34,6 +34,7 @@ import network.packets.Packet; import network.packets.swg.SWGPacket; import network.packets.swg.zone.server_ui.SuiCreatePageMessage; import network.packets.swg.zone.server_ui.SuiEventNotification; +import network.packets.swg.zone.server_ui.SuiForceClosePage; import resources.control.Intent; import resources.control.Service; import resources.player.Player; @@ -100,8 +101,15 @@ public class SuiService extends Service { } private void handleSuiWindowIntent(SuiWindowIntent i) { - if (i.getEvent() == SuiWindowEvent.NEW) - displayWindow(i.getPlayer(), i.getWindow()); + switch(i.getEvent()) { + case NEW: displayWindow(i.getPlayer(), i.getWindow()); break; + case CLOSE: { + SuiBaseWindow window = i.getWindow(); + if (window != null) closeWindow(i.getPlayer(), i.getWindow()); + else closeWindow(i.getPlayer(), i.getWindowId()); + } break; + default: break; + } } private void handleSuiEventNotification(Player player, SuiEventNotification p) { @@ -173,6 +181,35 @@ public class SuiService extends Service { activeWindows.add(window); } + private void closeWindow(Player player, SuiBaseWindow window) { + int id = window.getId(); + + List activeWindows = windows.get(player.getNetworkId()); + + if (activeWindows == null) { + Log.w("SuiService:CloseWindow", "Tried to close window id %i for player %s but it doesn't exist in the active windows.", id, player); + return; + } + + if (!activeWindows.remove(window)) { + Log.w("SuiService:CloseWindow", "Tried to close window id %i for player %s but it doesn't exist in the active windows.", id, player); + return; + } + + player.sendPacket(new SuiForceClosePage(id)); + } + + private void closeWindow(Player player, int windowId) { + List activeWindows = windows.get(player.getNetworkId()); + SuiBaseWindow window = activeWindows.get(windowId); + if (window == null) { + Log.w("SuiService:CloseWindow", "Cannot close window with id %i as it doesn't exist in player %s active windows", windowId, player); + return; + } + + closeWindow(player, window); + } + private SuiBaseWindow getWindowById(List windows, int id) { for (SuiBaseWindow window : windows) { if (window.getId() == id) diff --git a/src/utilities/IntentFactory.java b/src/utilities/IntentFactory.java index c98a705ee..b54a634d4 100644 --- a/src/utilities/IntentFactory.java +++ b/src/utilities/IntentFactory.java @@ -129,4 +129,22 @@ public final class IntentFactory { public void showSuiWindow(Player player, SuiBaseWindow suiWindow) { new SuiWindowIntent(player, suiWindow, SuiWindowIntent.SuiWindowEvent.NEW).broadcast(); } + + /** + * Closes a currently opened window on the client with the id of the SUI Window + * @param player Player that has the window to be closed + * @param suiWindow {@link SuiBaseWindow} to be closed + */ + public void closeSuiWindow(Player player, SuiBaseWindow suiWindow) { + new SuiWindowIntent(player, suiWindow, SuiWindowIntent.SuiWindowEvent.CLOSE).broadcast(); + } + + /** + * Closes a currently opened window on the client with the id of the SUI Window + * @param player Player that has the window to be closed + * @param windowId Window id of the {@link SuiBaseWindow} to close + */ + public void closeSuiWindow(Player player, int windowId) { + new SuiWindowIntent(player, null, windowId, SuiWindowIntent.SuiWindowEvent.CLOSE).broadcast(); + } }