package NET.worlds.console; import NET.worlds.core.IniFile; import NET.worlds.core.Std; import NET.worlds.network.BuddyListUpdateCmd; import NET.worlds.network.Galaxy; import NET.worlds.network.InfiniteWaitException; import NET.worlds.network.NetUpdate; import NET.worlds.network.NetworkObject; import NET.worlds.network.PacketTooLargeException; import NET.worlds.network.WorldServer; import NET.worlds.network.netPacket; import NET.worlds.network.whisperCmd; import NET.worlds.scape.AnimatedActionManager; import NET.worlds.scape.Drone; import NET.worlds.scape.FrameEvent; import NET.worlds.scape.MouseDownEvent; import NET.worlds.scape.Pilot; import NET.worlds.scape.PosableDrone; import NET.worlds.scape.PosableShape; import NET.worlds.scape.TeleportAction; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Event; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.Menu; import java.awt.MenuItem; import java.awt.PopupMenu; import java.io.IOException; import java.text.MessageFormat; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.StringTokenizer; import java.util.Vector; public class FriendsListPart extends QuantizedCanvas implements FramePart, DialogReceiver, DialogDisabled, NameListOwner, Comparator { private static final long serialVersionUID = 2875678557235430189L; private static final String oldIniItemName = "Friends"; private static final String iniItemName = "Friend"; private static int maxFriends = Gamma.shaperEnabled() ? 500 : 250; private static int absMaxFriends = 600; private static final String separator = ";"; private static final String whereQuery = "&|+where?"; private static final String whereResponse = "&|+where>"; VoiceChat chatter = new VoiceChat(); private static final int MOUSEMOVE = 0; private static final int MOUSEDRAG = 1; private static final int MOUSEDOWN = 2; private static final int MOUSEUP = 3; private static final int MOUSEENTER = 4; private static final int MOUSEEXIT = 5; private static final int BLANK = 0; private static final int NORMAL = 1; private static final int CURSED = 2; private static final int DOWN = 3; private static final int TELEPORT_IDLE = 0; private static final int TELEPORT_REQUEST_LOCATION = 1; private static final int TELEPORT_WAIT_FOR_LOCATION = 2; private static final int buttonWidth = 97; private static final int buttonHeight = 11; private static final int xText = 20; private static final int yText = 9; private static final int xTextClip = 94; private static Image friendsImage; private static Image moreFriendsImage; private static Font font; private static FriendsListPart active; private Vector friends = new Vector(); private Vector onlineFriends = new Vector(); private Vector mutedOnlineFriends = new Vector(); private Vector serverUpdates = new Vector(); private Object friendsMutex = new Object(); private int cursedButton = -1; private int clickedButton = -1; private boolean clickedButtonDown; private PopupMenu menu; private MenuItem teleportItem = new MenuItem(Console.message("Go-There")); private MenuItem emailItem = new MenuItem(Console.message("E-Mail")); private MenuItem muteItem = new MenuItem(Console.message("Mute")); private MenuItem whisperItem = new MenuItem(Console.message("Whisper")); private MenuItem voiceChatItem = new MenuItem(Console.message("Voice-Chat")); private MenuItem infoItem = new MenuItem(Console.message("Personal-I")); private MenuItem tradeItem = new MenuItem(Console.message("Talk-Trade")); private PopupMenu droneMenu; private MenuItem droneAddItem = new MenuItem(Console.message("Add-2-friends")); private MenuItem droneEmailItem = new MenuItem(Console.message("E-Mail")); private MenuItem droneMuteItem = new MenuItem(Console.message("Mute")); private MenuItem droneWhisperItem = new MenuItem(Console.message("Whisper")); private MenuItem droneVoiceChatItem = new MenuItem(Console.message("Voice-Chat")); private MenuItem droneInfoItem = new MenuItem(Console.message("Personal-I")); private MenuItem droneTradeItem = new MenuItem(Console.message("Talk-Trade")); private String activeFriendName = ""; private String teleportTarget; private int teleportState = 0; private int teleportWaitStartTime; private boolean teleportWaitSentMsg; private int friendsButtons; private int moreFriendsButton; private boolean moreFriendsActive; private MenuItem editItem; private Menu actionMenu; private MoreFriendsDialog moreFriendsDialog; private DefaultConsole console; private Galaxy galaxy; private IniFile serverSection; private boolean isDialogDisabled; private int showMenuY = -1; private static final String voiceChatWhisper = "&|+voicechat"; public FriendsListPart() { AnimatedActionManager.get(); if (font == null) { String friendsGif = IniFile.override().getIniString("friendsGif", "friends.gif"); friendsImage = ImageCanvas.getSystemImage(friendsGif, this); String moreFriendsGif = IniFile.override().getIniString("moreFriendsGif", Console.message("mfriends.gif")); moreFriendsImage = ImageCanvas.getSystemImage(moreFriendsGif, this); int fontSize = new Integer(Console.message("FriendsPointSize")); font = new Font(Console.message("FriendsFont"), 0, fontSize); } this.teleportItem.setFont(font); this.emailItem.setFont(font); this.muteItem.setFont(font); this.whisperItem.setFont(font); this.tradeItem.setFont(font); this.voiceChatItem.setFont(font); this.infoItem.setFont(font); this.menu = new PopupMenu(); this.menu.add(this.teleportItem); String prodName = IniFile.override().getIniString("ProductName", ""); if (!prodName.equalsIgnoreCase("RedLightWorld") && !prodName.equalsIgnoreCase("RedLightCenter")) { this.menu.add(this.emailItem); } this.menu.add(this.muteItem); this.menu.add(this.whisperItem); boolean allowTrading = IniFile.gamma().getIniInt("EnableTrading", 0) == 1 || NetUpdate.isInternalVersion(); if (allowTrading) { this.menu.add(this.tradeItem); } this.menu.add(this.voiceChatItem); if (!VoiceChat.voiceChatAvailable()) { this.voiceChatItem.setEnabled(false); } this.menu.add(this.infoItem); this.add(this.menu); this.droneAddItem.setFont(font); this.droneEmailItem.setFont(font); this.droneMuteItem.setFont(font); this.droneWhisperItem.setFont(font); this.droneTradeItem.setFont(font); this.droneVoiceChatItem.setFont(font); this.droneInfoItem.setFont(font); this.droneMenu = new PopupMenu(); this.droneMenu.setFont(font); this.droneMenu.add(this.droneAddItem); this.droneMenu.add(this.droneEmailItem); this.droneMenu.add(this.droneMuteItem); this.droneMenu.add(this.droneWhisperItem); if (allowTrading) { this.droneMenu.add(this.droneTradeItem); } this.droneMenu.add(this.droneVoiceChatItem); if (!VoiceChat.voiceChatAvailable()) { this.droneVoiceChatItem.setEnabled(false); } this.droneMenu.add(this.droneInfoItem); } @Override public void update(Graphics g) { this.paint(g); } @Override public void paint(Graphics g) { int height = this.getSize().height; int buttons = height / 11; synchronized (this.friendsMutex) { int count = this.onlineFriends.size(); this.moreFriendsButton = buttons - 1; if (count >= buttons) { this.friendsButtons = buttons - 1; this.moreFriendsActive = true; } else { this.friendsButtons = count; this.moreFriendsActive = false; } int y = buttons * 11; int extra = height - y; if (extra > 0) { g.setColor(Color.black); g.fillRect(0, 0, 97, extra); } for (int i = 0; i < buttons; i++) { int state = 1; if (i >= this.friendsButtons && !this.isMoreFriendsButton(i)) { state = 0; } else if (i == this.clickedButton) { state = this.clickedButtonDown ? 3 : 1; } else if (i == this.cursedButton) { state = 2; } this.drawButton(g, i, state); } } } @Override public int getRemainder(int proposedHeight) { int buttons = proposedHeight / 11; int y = buttons * 11; return proposedHeight - y; } @Override public Dimension preferredSize() { return new Dimension(97, 1); } @Override public Dimension minimumSize() { return this.preferredSize(); } @Override public boolean mouseMove(Event e, int x, int y) { return this.buttonAction(x, y, 0); } @Override public boolean mouseDown(Event e, int x, int y) { return this.buttonAction(x, y, 2); } @Override public boolean mouseUp(Event e, int x, int y) { if (this.buttonAction(x, y, 3)) { if (this.showMenuY != -1) { this.menu.show(this, 0, this.showMenuY); this.showMenuY = -1; } return true; } else { return false; } } @Override public boolean mouseDrag(Event e, int x, int y) { return this.buttonAction(x, y, 1); } @Override public boolean mouseEnter(Event e, int x, int y) { return this.buttonAction(x, y, 4); } @Override public boolean mouseExit(Event e, int x, int y) { return this.buttonAction(x, y, 5); } @Override public boolean handleEvent(Event event) { return this.isDialogDisabled ? false : super.handleEvent(event); } private void loadFriends() { if (this.friends.size() != 0) { this.friends.removeAllElements(); } if (Console.getActive().broadcastEnabled()) { maxFriends = 600; } for (int i = 0; i < absMaxFriends; i++) { String name = this.serverSection.getIniString("Friend" + i, ""); if (name.length() == 0) { break; } if (isValidUserName(name) && !icontains(this.friends, name)) { this.friends.addElement(name); } } if (this.friends.size() == 0) { String friendsStr = this.serverSection.getIniString("Friends", ""); StringTokenizer tokens = new StringTokenizer(friendsStr, ";"); while (tokens.hasMoreTokens() && this.friends.size() < absMaxFriends) { String namex = tokens.nextToken(); if (isValidUserName(namex) && !icontains(this.friends, namex)) { this.friends.addElement(namex); } } if (this.friends.size() != 0) { this.saveFriends(); this.serverSection.setIniString("Friends", ""); } } Collections.sort(this.friends, this); } void saveFriends() { if (this.serverSection != null) { int count = this.friends.size(); for (int i = 0; i < count; i++) { this.serverSection.setIniString("Friend" + i, this.friends.elementAt(i)); } this.serverSection.setIniString("Friend" + count, ""); } } private boolean isMoreFriendsButton(int button) { return button == this.moreFriendsButton && this.moreFriendsActive; } private Graphics drawButton(Graphics g, int button, int state) { Image image = button == this.moreFriendsButton ? moreFriendsImage : friendsImage; if (g != null || (g = this.getGraphics()) != null) { int y = button * 11; Graphics g1 = g.create(0, y, 97, 11); g1.drawImage(image, -state * 97, 0, null); if (button >= 0 && button < this.friendsButtons && button < this.onlineFriends.size()) { g1.clipRect(0, 0, 94, 11); g1.setFont(font); g1.setColor(Color.white); g1.drawString(this.onlineFriends.elementAt(button), 20, 9); } g1.dispose(); } return g; } private boolean buttonAction(int x, int y, int action) { synchronized (this.friendsMutex) { Graphics g = null; int button = y / 11; if ((button < 0 || button >= this.friendsButtons) && !this.isMoreFriendsButton(button)) { button = -1; } if (action != 0 && action != 4) { if (action == 5) { if (this.cursedButton != -1) { g = this.drawButton(g, this.cursedButton, 1); this.cursedButton = -1; } if (this.clickedButton != -1 && this.clickedButtonDown) { g = this.drawButton(g, this.clickedButton, 1); this.clickedButtonDown = false; } } else if (action == 2) { if (this.clickedButton != -1) { g = this.drawButton(g, this.clickedButton, 1); this.clickedButtonDown = false; } if ((this.clickedButton = button) != -1) { g = this.drawButton(g, this.clickedButton, 3); this.clickedButtonDown = true; } } else if (action == 1) { if (this.clickedButton != -1) { if (this.clickedButtonDown) { if (button != this.clickedButton) { g = this.drawButton(g, this.clickedButton, 1); this.clickedButtonDown = false; } } else if (button == this.clickedButton) { g = this.drawButton(g, this.clickedButton, 3); this.clickedButtonDown = true; } } } else if (action == 3) { this.cursedButton = button; if (this.clickedButtonDown) { if (this.cursedButton == this.clickedButton) { g = this.drawButton(g, this.clickedButton, 2); } else { g = this.drawButton(g, this.clickedButton, 1); } if (this.clickedButton == this.moreFriendsButton) { if (this.moreFriendsDialog == null) { this.moreFriendsDialog = new MoreFriendsDialog(this, this.menu, this.onlineFriends); } } else if (this.clickedButton >= 0 && this.clickedButton < this.onlineFriends.size()) { this.activeFriendName = this.onlineFriends.elementAt(this.clickedButton); assert this.activeFriendName != null; this.showMenuY = (this.clickedButton + 1) * 11; } } if (this.cursedButton != this.clickedButton) { g = this.drawButton(g, this.cursedButton, 2); } this.clickedButtonDown = false; this.clickedButton = -1; } } else if (button != this.cursedButton) { g = this.drawButton(g, this.cursedButton, 1); g = this.drawButton(g, this.cursedButton = button, 2); } if (g != null) { g.dispose(); } return true; } } private static boolean sendMsg(WorldServer server, netPacket packet) { try { server.sendNetworkMsg(packet); return true; } catch (InfiniteWaitException var3) { } catch (PacketTooLargeException var4) { } return false; } @Override public void activate(Console c, Container f, Console prev) { active = this; this.console = (DefaultConsole)c; this.console.getRender().add(this.droneMenu); this.editItem = c.addMenuItem(Console.message("Edit-Friends"), "Options"); this.editItem.setEnabled(this.friends != null); } @Override public void deactivate() { active = null; this.editItem = null; } @Override public boolean action(Event event, Object what) { if (event.target == this.editItem) { new EditNamesDialog(this, Console.message("Edit-Friends2"), Console.message("Add-Friend")); return true; } else { return this.maybeFriendAction(event.target); } } @Override public boolean handle(FrameEvent f) { synchronized (this.friendsMutex) { int count = this.serverUpdates.size(); if (count != 0) { WorldServer server = this.console.getServerNew(); if (server != null) { while (count-- != 0 && sendMsg(server, this.serverUpdates.elementAt(0))) { this.serverUpdates.removeElementAt(0); } } } } synchronized (this) { if (this.teleportState == 1) { WorldServer server = this.console.getServerNew(); if (server != null) { sendMsg(server, new whisperCmd(this.teleportTarget, "&|+where?")); this.teleportState = 2; this.teleportWaitStartTime = Std.getRealTime(); this.teleportWaitSentMsg = false; } else { Console.println(Console.message("Cant-go-there")); this.teleportState = 0; } } if (this.teleportState == 2) { int now = Std.getRealTime(); if (now > this.teleportWaitStartTime + 5000) { if (now > this.teleportWaitStartTime + 30000) { this.teleportState = 0; if (this.teleportWaitSentMsg) { Object[] arguments = new Object[]{new String(this.teleportTarget)}; Console.println(MessageFormat.format(Console.message("Cancel-teleport"), arguments)); } } else if (!this.teleportWaitSentMsg) { Object[] arguments = new Object[]{new String(this.teleportTarget)}; Console.println(MessageFormat.format(Console.message("Delay-locating"), arguments)); this.teleportWaitSentMsg = true; } } } return true; } } @Override public void dialogDisable(boolean disable) { if (this.isDialogDisabled = disable) { this.cursedButton = -1; this.clickedButton = -1; this.clickedButtonDown = false; this.repaint(); } } public void setServer(WorldServer server, IniFile serverSection) { this.serverSection = serverSection; this.galaxy = server.getGalaxy(); assert serverSection != null; assert this.galaxy != null; this.loadFriends(); if (this.editItem != null) { this.editItem.setEnabled(true); } this.sendAll(server); } public void maybeServerDisconnect() { if (this.galaxy != null) { if (this.editItem != null) { this.editItem.setEnabled(false); } this.clearAll(); } } public static boolean tryToRun(String s) { try { Runtime.getRuntime().exec(s); return true; } catch (IOException var2) { return false; } } private boolean maybeFriendAction(Object target) { if (target == this.emailItem || target == this.droneEmailItem) { EMailPart.showMessage(this.console, this.activeFriendName); } else if (target == this.whisperItem || target == this.droneWhisperItem) { Console.startWhispering(this.activeFriendName); } else if (target == this.voiceChatItem || target == this.droneVoiceChatItem) { this.chatter.beginChat(this.activeFriendName, this.console); } else if (target == this.droneAddItem) { if (this.mayAddNameListName(Console.getFrame())) { this.addNameListName(this.activeFriendName); } } else if (target == this.teleportItem) { synchronized (this) { this.teleportTarget = this.activeFriendName; if (this.teleportState == 2 && this.teleportWaitSentMsg) { Console.println(Console.message("Cancel-new-tele")); } this.teleportState = 1; } } else if (target == this.muteItem || target == this.droneMuteItem) { if (this.console.getMutes().mayAddNameListName(Console.getFrame())) { this.console.getMutes().addNameListName(this.activeFriendName); } } else if (target != this.infoItem && target != this.droneInfoItem) { if (target != this.tradeItem && target != this.droneTradeItem) { return false; } WhisperManager.whisperManager().startToTrade(this.activeFriendName); } else { new PersonalInfoDownload(this.activeFriendName, this.console); } return true; } private void clearAll() { if (this.galaxy != null) { synchronized (this.friendsMutex) { this.onlineFriends.removeAllElements(); this.mutedOnlineFriends.removeAllElements(); } if (active == this) { this.repaint(); } this.galaxy.sentFriendsList(false); } } private void sendAll(WorldServer server) { if (!this.galaxy.sentFriendsList()) { synchronized (this.friendsMutex) { int count = this.friends.size(); for (int i = 0; i < count; i++) { sendMsg(server, new BuddyListUpdateCmd(this.friends.elementAt(i), 1)); } } this.galaxy.sentFriendsList(true); } } private static String getWorldName(String url) { int rindex = url.indexOf(".world#"); int windex; return rindex == -1 || (windex = url.lastIndexOf(47, rindex)) == -1 && (windex = url.lastIndexOf(58, rindex)) == -1 ? null : url.substring(windex + 1, rindex); } public static void processWhisper(WorldServer server, String user, String text) { if (active != null && active.galaxy == server.getGalaxy()) { active.instanceProcessWhisper(server, user, text); } } private synchronized void instanceProcessWhisper(WorldServer server, String user, String text) { if (text.startsWith("&|+where?")) { Pilot pilot; String url; if ((pilot = Pilot.getActive()) != null && (url = pilot.getTeleportURL()) != null) { if (this.console.getSpecialGuest()) { int i = url.indexOf(60); int j = url.indexOf(62); url = url.substring(0, i) + url.substring(j + 1); } if (Pilot.getActive().getRoom().getAllowTeleport()) { sendMsg(server, new whisperCmd(user, "&|+where>" + url)); } } } else if (text.startsWith("&|+where>")) { if (this.teleportState == 2 && this.teleportTarget.equals(user)) { String pos = text.substring("&|+where>".length()); boolean valid = false; String targetWorld = getWorldName(pos); if (!pos.startsWith("home:") && !pos.startsWith("http://")) { if (targetWorld != null && targetWorld.length() > 0) { Pilot pilot = Pilot.getActive(); if (pilot != null) { String url = pilot.getTeleportURL(); if (url != null && targetWorld.equals(getWorldName(url))) { valid = true; pos = url.substring(0, url.lastIndexOf(35)) + pos.substring(pos.lastIndexOf(35)); } } } if (!valid) { String s = WorldsMarkPart.findPackage(targetWorld); if (s != null) { valid = true; pos = "home:" + s + "/" + s + ".world" + pos.substring(pos.lastIndexOf(35)); } } } else { valid = true; } if (valid) { TeleportAction.teleport(pos, null); if (this.teleportWaitSentMsg) { Object[] arguments = new Object[]{new String(this.teleportTarget)}; Console.println(MessageFormat.format(Console.message("Found-tele"), arguments)); } } else { Object[] arguments = new Object[]{new String(this.teleportTarget), new String(targetWorld)}; String msg = MessageFormat.format(Console.message("Cant-go-world"), arguments); Console.println(msg); } this.teleportState = 0; this.teleportTarget = null; } } else if (text.startsWith("&|+voicechat")) { this.chatter.handleChatWhisper(user, text, this.console); } else if (text.startsWith(VoiceChat.VCdebugCommand)) { VoiceChat.setExtra(text); } else if (text.startsWith(VoiceChat.VCdebugCommandReset)) { VoiceChat.resetExtra(); } } @Override public int getNameListCount() { return this.friends.size(); } @Override public String getNameListName(int index) { return this.friends.elementAt(index); } @Override public void removeNameListName(int index) { synchronized (this.friendsMutex) { String name = this.friends.elementAt(index); this.friends.removeElementAt(index); this.saveFriends(); if ((index = iindexOf(this.onlineFriends, name)) != -1) { this.onlineFriends.removeElementAt(index); if (active == this) { this.repaint(); } } if ((index = iindexOf(this.mutedOnlineFriends, name)) != -1) { this.mutedOnlineFriends.removeElementAt(index); } this.serverUpdates.addElement(new BuddyListUpdateCmd(name, 0)); } } @Override public boolean mayAddNameListName(java.awt.Window currentWindow) { if (this.friends.size() < maxFriends) { return true; } else { Object[] arguments = new Object[]{new String("" + maxFriends)}; new OkCancelDialog( currentWindow, null, Console.message("Too-many-names"), null, Console.message("OK"), MessageFormat.format(Console.message("You-are-limitedF"), arguments), true ); return false; } } @Override public int addNameListName(String name) { synchronized (this.friendsMutex) { int index = iindexOf(this.friends, name); if (index != -1) { return index; } else { this.friends.addElement(name); Collections.sort(this.friends, this); this.saveFriends(); this.serverUpdates.addElement(new BuddyListUpdateCmd(name, 1)); return this.friends.size() - 1; } } } public int compare(String arg0, String arg1) { return arg0.compareToIgnoreCase(arg1); } public static void droneClick(Drone who, MouseDownEvent event) { if (active != null) { active.instanceDroneClick(who, event); } } private void instanceDroneClick(Drone who, MouseDownEvent event) { String tmp = who.getLongID(); if (tmp != null) { this.activeFriendName = tmp; Object[] arguments = new Object[]{new String(this.activeFriendName)}; this.droneAddItem = new MenuItem(MessageFormat.format(Console.message("Add-to-friends"), arguments)); this.droneMenu.remove(0); this.droneAddItem.setFont(font); this.droneMenu.insert(this.droneAddItem, 0); this.droneAddItem.setEnabled(!icontains(this.friends, this.activeFriendName)); if (this.actionMenu != null) { this.droneMenu.remove(this.actionMenu); } if (who instanceof PosableDrone) { PosableDrone pd = (PosableDrone)who; PosableShape ps = pd.getInternalPosableShape(); if (ps != null) { this.actionMenu = new Menu(Console.message("Actions")); if (AnimatedActionManager.get().buildActionMenu(this.actionMenu, ps)) { this.droneMenu.add(this.actionMenu); this.actionMenu.addActionListener(AnimatedActionManager.get()); } } } this.droneMenu.show(this.console.getRender(), event.x, event.y); } } public static void processBuddyListNotify(WorldServer server, String name, int state) { Galaxy g = server.getGalaxy(); Enumeration consoleList = g.getConsoles(); while (consoleList.hasMoreElements()) { Object c = consoleList.nextElement(); if (c instanceof DefaultConsole) { FriendsListPart target = ((DefaultConsole)c).getFriends(); if (state < 2) { boolean muted = MuteListPart.isMuted(server, name); if (state == 1) { target.addOnlineFriend(name, muted); } else { target.removeOnlineFriend(name, muted); } } else { assert name.length() == 0; target.clearAll(); } } } if (state == 2) { consoleList = g.getConsoles(); while (consoleList.hasMoreElements()) { Object c = consoleList.nextElement(); if (c instanceof DefaultConsole) { FriendsListPart target = ((DefaultConsole)c).getFriends(); target.sendAll(server); break; } } } } public static String ilookup(Vector v, String name) { int count = v.size(); for (int i = 0; i < count; i++) { String ele = v.elementAt(i); if (ele.equalsIgnoreCase(name)) { return ele; } } return null; } public static int iindexOf(Vector v, String name) { int count = v.size(); for (int i = 0; i < count; i++) { String ele = v.elementAt(i); if (ele.equalsIgnoreCase(name)) { return i; } } return -1; } public static boolean icontains(Vector v, String name) { return iindexOf(v, name) != -1; } public void changeMuteState(String name, boolean muted) { synchronized (this.friendsMutex) { if (icontains(this.friends, name)) { if (muted) { name = ilookup(this.onlineFriends, name); if (name != null) { this.removeOnlineFriend(name, false); this.addOnlineFriend(name, true); } } else { name = ilookup(this.mutedOnlineFriends, name); if (name != null) { this.removeOnlineFriend(name, true); this.addOnlineFriend(name, false); } } } } } private void listChanged() { this.cursedButton = -1; this.clickedButton = -1; this.clickedButtonDown = false; this.repaint(); } private void addOnlineFriend(String name, boolean muted) { synchronized (this.friendsMutex) { if (this.friends != null && icontains(this.friends, name)) { if (!muted && !icontains(this.onlineFriends, name)) { this.onlineFriends.addElement(name); if (active == this) { this.listChanged(); if (this.moreFriendsDialog != null) { this.moreFriendsDialog.addName(name); } } } else if (muted && !icontains(this.mutedOnlineFriends, name)) { this.mutedOnlineFriends.addElement(name); } } } } private void removeOnlineFriend(String name, boolean muted) { synchronized (this.friendsMutex) { if (!muted) { int index = this.onlineFriends.indexOf(name); if (index != -1) { this.onlineFriends.removeElementAt(index); if (active == this) { this.listChanged(); if (this.moreFriendsDialog != null) { this.moreFriendsDialog.removeName(index); } } } } else { this.mutedOnlineFriends.removeElement(name); } } } @Override public void dialogDone(Object who, boolean confirmed) { synchronized (this.friendsMutex) { if (who == this.moreFriendsDialog) { this.moreFriendsDialog = null; } } } public static boolean isValidUserName(String name) { String validChars = "_-"; name = Console.parseUnicode(name); int length = name.length(); if (length >= 2 && length <= 16) { char[] nameChars = name.toCharArray(); for (int i = 0; i < length; i++) { if (!Character.isLetterOrDigit(nameChars[i]) && validChars.indexOf(nameChars[i]) == -1) { return false; } } return true; } else { return false; } } void moreFriendsAction(String name, MenuItem function) { this.activeFriendName = name; assert this.activeFriendName != null; this.maybeFriendAction(function); } }