Java tutorial
/* * This file is part of the RS3Emulator social module. * * RS3Emulator is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * RS3Emulator 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with RS3Emulator. If not, see <http://www.gnu.org/licenses/>. */ package org.virtue.game.logic.social; import java.io.FileNotFoundException; import org.virtue.Launcher; import org.virtue.game.config.OutgoingOpcodes; import org.virtue.game.logic.World; import org.virtue.game.logic.node.entity.player.Player; import org.virtue.game.logic.node.interfaces.impl.ClanSettingsInterface; import org.virtue.game.logic.node.interfaces.impl.FriendsChatSettings; import org.virtue.game.logic.social.clans.ClanChannelAPI; import org.virtue.game.logic.social.internal.InternalFriendManager; import org.virtue.game.logic.social.internal.InternalFriendsChatManager; import org.virtue.game.logic.social.internal.InternalSocialUser; import org.virtue.game.logic.social.messages.PublicMessage; import org.virtue.network.io.IOHub; import org.virtue.network.protocol.messages.ClientScriptVar; import org.virtue.network.protocol.messages.GameMessage.MessageOpcode; import org.virtue.network.protocol.packet.encoder.impl.EmptyPacketEncoder; import org.virtue.network.protocol.packet.encoder.impl.chat.OnlineStatusEncoder; import org.virtue.network.protocol.packet.encoder.impl.chat.PublicMessageEncoder; import org.virtue.utility.StringUtils; import org.virtue.utility.StringUtils.FormatType; import com.google.gson.JsonElement; import com.google.gson.JsonObject; /** * Contains the tools necessary to manage chat for the player, including interacting with friends chat channels, friends and ignores management, and public messaging * * @author Sundays211 * @since Apr 17, 2014 */ public class ChatManager { private enum ChannelStage { NONE, JOINING, JOINED, LEAVING } private static final FriendsChatAPI friendsChatManager = new InternalFriendsChatManager(); /** * Represents the player. */ private final Player player; private final InternalSocialUser socialUser; /** * Represents the type of message that the next message(s) will be */ private ChatType chatType; /** * Represents the current online status of the player */ private OnlineStatus onlineStatus = OnlineStatus.FRIENDS; /** * Represents the friends/ignores manager for the player */ private FriendManagerAPI friendManager; //=================================Friends chat data=================================// /** * Represents the name of the channel the player is currently in, or "null" if the player is not in a channel */ private String currentFriendsChat = null; /** * Represents the name of the last channel the player was or "null" if the player has never been in a friends chat */ private String lastFriendsChat = ""; /** * Represents whether the player should automatically join the last friends chat they were in when they log into the game. */ private boolean autoJoinFriendsChat = false; /** * Represents the current friends chat status of the player */ private ChannelStage channelStage = ChannelStage.NONE; /** * Represents the friends chat settings interface for the player */ private FriendsChatSettings friendsChatSettings = null; //=================================Clan data=================================// private long myClanHash = 0L; private long guestClanHash = 0L; private boolean inClanChannel = false; private ClanSettingsInterface clanSettings = null; /** * Constructs a new {@code ChatManager} instance for the specified player * @param player The player */ public ChatManager(Player player) { this.player = player; this.socialUser = new InternalSocialUser(player); String protocolName = player.getAccount().getUsername().getAccountNameAsProtocol(); if (IOHub.getFriendsIO().exists(protocolName)) { try { friendManager = IOHub.getFriendsIO().load(protocolName, new InternalSocialUser(player)); } catch (FileNotFoundException e) { friendManager = new InternalFriendManager(new InternalSocialUser(player)); } } else { friendManager = new InternalFriendManager(new InternalSocialUser(player)); } } /** * Sets the type for the player's chat messages * @param typeCode The code representing the type */ public void setChatType(int typeCode) { setChatType(ChatType.forCode(typeCode)); } /** * Sets the type for the player's chat messages * @param type The chat type */ public void setChatType(ChatType type) { chatType = type; } public void init(boolean lobby) { player.getPacketDispatcher().dispatchClientScriptVar(new ClientScriptVar(1303, lastFriendsChat, autoJoinFriendsChat ? 1 : 0, lastFriendsChat.length() == 0 ? 0 : 1, 93519895));//Runscript: [1303, 93519895, 1, 1, Test] player.getAccount().getSession().getTransmitter().send(OnlineStatusEncoder.class, onlineStatus); player.getAccount().getSession().getTransmitter().send(EmptyPacketEncoder.class, OutgoingOpcodes.UNLOCK_FRIENDS_LIST); friendManager.init(); Launcher.getClanManager().registerPlayer(socialUser); if (myClanHash != 0L) { Launcher.getClanManager().getChannelManager().joinMyChannel(socialUser); } } /** * Handles the disconnection of the player's friends list and friends chat, and saves the player's friend data */ public void disconnect() { IOHub.getFriendsIO().save(player.getAccount().getUsername().getAccountNameAsProtocol(), friendManager); friendManager.shutdown(); if (channelStage.equals(ChannelStage.JOINED)) { friendsChatManager.leaveChannel(socialUser, true); } Launcher.getClanManager().deregisterPlayer(socialUser); //Leave both the clan channel and guest clan channel Launcher.getClanManager().getChannelManager().leaveChannel(socialUser, true, true); Launcher.getClanManager().getChannelManager().leaveChannel(socialUser, false, true); } /** * Gets the manager for this player's friends and ignores * @return The friend manager */ public FriendManagerAPI getFriendManager() { return friendManager; } public ClanChannelAPI getClanChatManager() { return Launcher.getClanManager().getChannelManager(); } public SocialUserAPI getSocialUser() { return socialUser; } public JsonObject serialiseData() { JsonObject chatData = new JsonObject(); chatData.addProperty("onlineStatus", onlineStatus.getStatusCode()); chatData.addProperty("lastFriendsChat", lastFriendsChat); chatData.addProperty("autoJoinFc", currentFriendsChat != null); chatData.addProperty("clanHash", myClanHash); return chatData; } public void deserialiseData(JsonObject chatData) { onlineStatus = OnlineStatus.forCode(chatData.get("onlineStatus").getAsInt()); if (onlineStatus == null) { onlineStatus = OnlineStatus.FRIENDS; } lastFriendsChat = chatData.get("lastFriendsChat").getAsString(); autoJoinFriendsChat = chatData.get("autoJoinFc").getAsBoolean(); JsonElement clanData = chatData.get("clanHash"); if (clanData != null) { myClanHash = clanData.getAsLong(); } } /** * Gets the type for the player's chat messages * @return */ public ChatType getChatType() { return chatType; } //=================================Friends chat section=================================// /** * Handles a request to join or leave a friends chat channel * @param name The name of the channel to join (or an empty string to leave) */ public void handleFriendsChatJoin(String name) { if (name.isEmpty()) { if (channelStage.equals(ChannelStage.LEAVING)) { player.getPacketDispatcher().dispatchMessage("Leave request already in progress - please wait...", MessageOpcode.FRIENDS_CHAT_SYSTEM); } else if (channelStage.equals(ChannelStage.NONE)) { player.getPacketDispatcher().dispatchMessage("You are not currently in a channel.", MessageOpcode.FRIENDS_CHAT_SYSTEM); } else if (channelStage.equals(ChannelStage.JOINED)) { channelStage = ChannelStage.LEAVING; friendsChatManager.leaveChannel(socialUser, false); } } else { if (channelStage.equals(ChannelStage.LEAVING) || channelStage.equals(ChannelStage.JOINED)) { player.getPacketDispatcher().dispatchMessage( "Please wait until you are logged out of your previous channel.", MessageOpcode.FRIENDS_CHAT_SYSTEM); } else if (channelStage.equals(ChannelStage.JOINING)) { player.getPacketDispatcher().dispatchMessage( "Already attempting to join a channel - please wait...", MessageOpcode.FRIENDS_CHAT_SYSTEM); } else if (channelStage.equals(ChannelStage.NONE)) { player.getPacketDispatcher().dispatchMessage("Attempting to join channel...", MessageOpcode.FRIENDS_CHAT_SYSTEM); channelStage = ChannelStage.JOINING; friendsChatManager.joinChannel(socialUser, name); } } } public String getCurrentChannelOwner() { return currentFriendsChat; } public void setCurrentChannelOwner(String ownerName) { currentFriendsChat = ownerName; if (ownerName == null) { channelStage = ChannelStage.NONE; } else { lastFriendsChat = ownerName; channelStage = ChannelStage.JOINED; } } public String getLastFriendsChat() { return lastFriendsChat; } public void setLastFriendsChat(String lastFriendsChat) { this.lastFriendsChat = lastFriendsChat; } public FriendsChatSettings getFriendsChatSettings() { return friendsChatSettings; } public void setFriendsChatSettings(FriendsChatSettings friendsChatSettings) { this.friendsChatSettings = friendsChatSettings; } public void handleFriendsChatMessage(String message) { String formattedMessage = StringUtils.format(message, FormatType.DISPLAY); friendsChatManager.sendMessage(socialUser, formattedMessage); } public void handleFriendsChatKick(String name) { friendsChatManager.kickBanUser(socialUser, name); } //=================================Clan section=================================// public long getMyClanHash() { return myClanHash; } public void setMyClanHash(long myClanHash) { this.myClanHash = myClanHash; } public long getGuestClanHash() { return guestClanHash; } public void setGuestClanHash(long clanHash) { this.guestClanHash = clanHash; } public boolean inClanChannel() { return inClanChannel; } public void setInClanChannel(boolean inClanChannel) { this.inClanChannel = inClanChannel; } public void joinMyClanChannel() { if (!inClanChannel) { Launcher.getClanManager().getChannelManager().joinMyChannel(socialUser); } } public void joinGuestChannel(String clanName) { if (guestClanHash == 0L) { Launcher.getClanManager().getChannelManager().joinGuestChannel(socialUser, clanName); } } public void leaveClanChannel(boolean isGuest) { Launcher.getClanManager().getChannelManager().leaveChannel(socialUser, isGuest, false); } public void handleClanChannelMessage(String message, boolean isGuest) { String formattedMessage = StringUtils.format(message, FormatType.DISPLAY); Launcher.getClanManager().getChannelManager().sendMessage(socialUser, formattedMessage, isGuest); } public void setClanSettings(ClanSettingsInterface settings) { this.clanSettings = settings; } public ClanSettingsInterface getClanSettingsInterface() { return clanSettings; } /** * Handles the specified public chat message * @param message The message * @param colourEffect The colour effect * @param moveEffect The movement effect */ public void handlePublicMessage(String message, int colourEffect, int moveEffect) { System.out.println("Received message: message=" + message + ", type=" + chatType + ", colour=" + colourEffect + ", move=" + moveEffect); String formattedMessage = StringUtils.format(message, FormatType.DISPLAY); int effects = (colourEffect << 8) | (moveEffect & 0xff); PublicMessage msgObject = new PublicMessage(formattedMessage, effects, player.getIndex(), player.getAccount().getRank()); for (Player p : World.getWorld().getPlayers()) { if (p == null || !p.exists() || p.getViewport().getLocalPlayers()[player.getIndex()] == null) { continue; } p.getAccount().getSession().getTransmitter().send(PublicMessageEncoder.class, msgObject); } } public void setOnlineStatus(OnlineStatus status) { this.onlineStatus = status; friendManager.setOnlineStatus(status); } public OnlineStatus getOnlineStatus() { return onlineStatus; } public static byte[] generateMessageHash() { byte[] hash = new byte[5]; Launcher.getRandom().nextBytes(hash); return hash; } }