diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/console/FriendsListPart.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/console/FriendsListPart.java')
| -rw-r--r-- | NET/worlds/console/FriendsListPart.java | 988 |
1 files changed, 988 insertions, 0 deletions
diff --git a/NET/worlds/console/FriendsListPart.java b/NET/worlds/console/FriendsListPart.java new file mode 100644 index 0000000..583ee9a --- /dev/null +++ b/NET/worlds/console/FriendsListPart.java @@ -0,0 +1,988 @@ +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<String> { + 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<String> friends = new Vector<String>(); + private Vector<String> onlineFriends = new Vector<String>(); + private Vector<String> mutedOnlineFriends = new Vector<String>(); + private Vector<BuddyListUpdateCmd> serverUpdates = new Vector<BuddyListUpdateCmd>(); + 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<NetworkObject> 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<String> 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<String> 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<String> 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); + } +} |