From 860d446d28776ec842fa53e8e08538d4e093d6e9 Mon Sep 17 00:00:00 2001 From: snowleo Date: Wed, 12 Oct 2011 03:14:07 +0200 Subject: EssentialsUpdate WIP --- .../earth2me/essentials/update/EssentialsHelp.java | 601 ++++++++++ .../essentials/update/EssentialsUpdate.java | 66 ++ .../com/earth2me/essentials/update/GetFile.java | 112 ++ .../com/earth2me/essentials/update/ModuleInfo.java | 35 + .../earth2me/essentials/update/PastieUpload.java | 40 + .../com/earth2me/essentials/update/PostToUrl.java | 66 ++ .../earth2me/essentials/update/UpdateCheck.java | 203 ++++ .../com/earth2me/essentials/update/UpdateFile.java | 204 ++++ .../earth2me/essentials/update/UpdateProcess.java | 128 +++ .../essentials/update/UpdatesDownloader.java | 19 + .../com/earth2me/essentials/update/Version.java | 173 +++ .../earth2me/essentials/update/VersionInfo.java | 48 + .../earth2me/essentials/update/states/Modules.java | 7 + .../f00f/net/irc/martyr/ClientStateMonitor.java | 67 ++ .../src/f00f/net/irc/martyr/Command.java | 18 + .../src/f00f/net/irc/martyr/CommandObserver.java | 5 + .../src/f00f/net/irc/martyr/CommandRegister.java | 118 ++ .../src/f00f/net/irc/martyr/CommandSender.java | 14 + .../src/f00f/net/irc/martyr/CronManager.java | 80 ++ .../src/f00f/net/irc/martyr/ForwardObservable.java | 66 ++ .../f00f/net/irc/martyr/GenericAutoService.java | 54 + .../net/irc/martyr/GenericCommandAutoService.java | 79 ++ .../src/f00f/net/irc/martyr/IRCConnection.java | 1163 ++++++++++++++++++++ .../src/f00f/net/irc/martyr/InCommand.java | 99 ++ .../src/f00f/net/irc/martyr/InputHandler.java | 130 +++ EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java | 103 ++ .../src/f00f/net/irc/martyr/OutCommand.java | 24 + .../src/f00f/net/irc/martyr/State.java | 31 + .../src/f00f/net/irc/martyr/StateObserver.java | 8 + .../src/f00f/net/irc/martyr/TimerTaskCommand.java | 57 + .../f00f/net/irc/martyr/clientstate/Channel.java | 373 +++++++ .../net/irc/martyr/clientstate/ClientState.java | 193 ++++ .../f00f/net/irc/martyr/clientstate/Member.java | 114 ++ .../net/irc/martyr/commands/AbstractCommand.java | 32 + .../net/irc/martyr/commands/AbstractInCommand.java | 174 +++ .../f00f/net/irc/martyr/commands/ActionCtcp.java | 12 + .../irc/martyr/commands/ChannelModeCommand.java | 189 ++++ .../f00f/net/irc/martyr/commands/CtcpMessage.java | 129 +++ .../f00f/net/irc/martyr/commands/CtcpNotice.java | 131 +++ .../net/irc/martyr/commands/InviteCommand.java | 90 ++ .../f00f/net/irc/martyr/commands/IsonCommand.java | 144 +++ .../f00f/net/irc/martyr/commands/JoinCommand.java | 131 +++ .../f00f/net/irc/martyr/commands/KickCommand.java | 110 ++ .../net/irc/martyr/commands/MessageCommand.java | 127 +++ .../f00f/net/irc/martyr/commands/ModeCommand.java | 237 ++++ .../f00f/net/irc/martyr/commands/NamesCommand.java | 77 ++ .../f00f/net/irc/martyr/commands/NickCommand.java | 97 ++ .../net/irc/martyr/commands/NoticeCommand.java | 129 +++ .../f00f/net/irc/martyr/commands/PartCommand.java | 126 +++ .../f00f/net/irc/martyr/commands/PassCommand.java | 33 + .../f00f/net/irc/martyr/commands/PingCommand.java | 67 ++ .../f00f/net/irc/martyr/commands/PongCommand.java | 39 + .../f00f/net/irc/martyr/commands/QuitCommand.java | 132 +++ .../f00f/net/irc/martyr/commands/RawCommand.java | 58 + .../f00f/net/irc/martyr/commands/TopicCommand.java | 80 ++ .../net/irc/martyr/commands/UnknownCommand.java | 38 + .../f00f/net/irc/martyr/commands/UserCommand.java | 46 + .../net/irc/martyr/commands/UserModeCommand.java | 99 ++ .../net/irc/martyr/commands/WelcomeCommand.java | 125 +++ .../f00f/net/irc/martyr/commands/WhoisCommand.java | 40 + .../irc/martyr/errors/AlreadyRegisteredError.java | 40 + .../irc/martyr/errors/CannotSendToChanError.java | 47 + .../net/irc/martyr/errors/CantKillServerError.java | 40 + .../irc/martyr/errors/ChanOPrivsNeededError.java | 48 + .../net/irc/martyr/errors/ChannelBannedError.java | 49 + .../irc/martyr/errors/ChannelInviteOnlyError.java | 48 + .../net/irc/martyr/errors/ChannelLimitError.java | 50 + .../irc/martyr/errors/ChannelWrongKeyError.java | 50 + .../irc/martyr/errors/ErroneusNicknameError.java | 47 + .../f00f/net/irc/martyr/errors/FileErrorError.java | 39 + .../f00f/net/irc/martyr/errors/GenericError.java | 14 + .../net/irc/martyr/errors/GenericJoinError.java | 67 ++ .../f00f/net/irc/martyr/errors/KeySetError.java | 45 + .../net/irc/martyr/errors/LoadTooHighError.java | 49 + .../net/irc/martyr/errors/NeedMoreParamsError.java | 47 + .../net/irc/martyr/errors/NickCollisionError.java | 48 + .../f00f/net/irc/martyr/errors/NickInUseError.java | 63 ++ .../net/irc/martyr/errors/NoAdminInfoError.java | 47 + .../f00f/net/irc/martyr/errors/NoLoginError.java | 48 + .../f00f/net/irc/martyr/errors/NoMotdError.java | 39 + .../irc/martyr/errors/NoNicknameGivenError.java | 39 + .../net/irc/martyr/errors/NoOperHostError.java | 40 + .../f00f/net/irc/martyr/errors/NoOriginError.java | 40 + .../net/irc/martyr/errors/NoPermForHostError.java | 40 + .../net/irc/martyr/errors/NoPrivilegesError.java | 40 + .../net/irc/martyr/errors/NoRecipientError.java | 38 + .../net/irc/martyr/errors/NoSuchChannelError.java | 46 + .../net/irc/martyr/errors/NoSuchNickError.java | 47 + .../net/irc/martyr/errors/NoSuchServerError.java | 46 + .../net/irc/martyr/errors/NoTextToSendError.java | 41 + .../net/irc/martyr/errors/NoTopLevelError.java | 48 + .../net/irc/martyr/errors/NotOnChannelError.java | 47 + .../net/irc/martyr/errors/NotRegisteredError.java | 40 + .../net/irc/martyr/errors/PasswdMismatchError.java | 40 + .../net/irc/martyr/errors/SummonDisabledError.java | 40 + .../irc/martyr/errors/TooManyChannelsError.java | 46 + .../net/irc/martyr/errors/TooManyTargetsError.java | 47 + .../irc/martyr/errors/UModeUnknownFlagError.java | 40 + .../net/irc/martyr/errors/UnknownCommandError.java | 46 + .../f00f/net/irc/martyr/errors/UnknownError.java | 69 ++ .../net/irc/martyr/errors/UnknownModeError.java | 45 + .../irc/martyr/errors/UserNotInChannelError.java | 54 + .../net/irc/martyr/errors/UserOnChannelError.java | 54 + .../net/irc/martyr/errors/UsersDisabledError.java | 40 + .../net/irc/martyr/errors/UsersDontMatchError.java | 39 + .../net/irc/martyr/errors/WasNoSuchNickError.java | 47 + .../net/irc/martyr/errors/WildTopLevelError.java | 48 + .../irc/martyr/errors/YoureBannedCreepError.java | 40 + .../src/f00f/net/irc/martyr/modes/GenericMode.java | 77 ++ .../src/f00f/net/irc/martyr/modes/README | 8 + .../irc/martyr/modes/channel/AnonChannelMode.java | 44 + .../f00f/net/irc/martyr/modes/channel/BanMode.java | 38 + .../irc/martyr/modes/channel/ExceptionMode.java | 38 + .../martyr/modes/channel/GenericChannelMask.java | 16 + .../martyr/modes/channel/GenericChannelMode.java | 23 + .../irc/martyr/modes/channel/InviteMaskMode.java | 30 + .../irc/martyr/modes/channel/InviteOnlyMode.java | 32 + .../f00f/net/irc/martyr/modes/channel/KeyMode.java | 31 + .../net/irc/martyr/modes/channel/LimitMode.java | 31 + .../irc/martyr/modes/channel/ModeratedMode.java | 31 + .../net/irc/martyr/modes/channel/NoExtMsgMode.java | 30 + .../net/irc/martyr/modes/channel/OperMode.java | 31 + .../net/irc/martyr/modes/channel/PrivateMode.java | 50 + .../net/irc/martyr/modes/channel/SecretMode.java | 50 + .../irc/martyr/modes/channel/TopicLockMode.java | 27 + .../net/irc/martyr/modes/channel/VoiceMode.java | 34 + .../net/irc/martyr/modes/user/GenericUserMode.java | 24 + .../net/irc/martyr/modes/user/InvisibleMode.java | 22 + .../net/irc/martyr/replies/AbstractWhoisReply.java | 58 + .../src/f00f/net/irc/martyr/replies/AwayReply.java | 49 + .../irc/martyr/replies/ChannelCreationReply.java | 78 ++ .../f00f/net/irc/martyr/replies/GenericReply.java | 16 + .../net/irc/martyr/replies/GenericStringReply.java | 23 + .../net/irc/martyr/replies/LUserClientReply.java | 28 + .../f00f/net/irc/martyr/replies/LUserMeReply.java | 28 + .../f00f/net/irc/martyr/replies/LUserOpReply.java | 36 + .../f00f/net/irc/martyr/replies/ListEndReply.java | 31 + .../src/f00f/net/irc/martyr/replies/ListReply.java | 63 ++ .../net/irc/martyr/replies/ListStartReply.java | 31 + .../src/f00f/net/irc/martyr/replies/ModeReply.java | 54 + .../f00f/net/irc/martyr/replies/NamesEndReply.java | 47 + .../f00f/net/irc/martyr/replies/NamesReply.java | 89 ++ .../f00f/net/irc/martyr/replies/NowAwayReply.java | 43 + .../net/irc/martyr/replies/TopicInfoReply.java | 80 ++ .../f00f/net/irc/martyr/replies/UnAwayReply.java | 43 + .../f00f/net/irc/martyr/replies/UnknownReply.java | 66 ++ .../net/irc/martyr/replies/WhoisChannelsReply.java | 70 ++ .../f00f/net/irc/martyr/replies/WhoisEndReply.java | 37 + .../net/irc/martyr/replies/WhoisIdleReply.java | 68 ++ .../net/irc/martyr/replies/WhoisServerReply.java | 61 + .../net/irc/martyr/replies/WhoisUserReply.java | 54 + .../src/f00f/net/irc/martyr/services/AutoJoin.java | 157 +++ .../net/irc/martyr/services/AutoReconnect.java | 271 +++++ .../f00f/net/irc/martyr/services/AutoRegister.java | 289 +++++ .../net/irc/martyr/services/AutoResponder.java | 82 ++ .../src/f00f/net/irc/martyr/util/CtcpUtil.java | 99 ++ .../src/f00f/net/irc/martyr/util/FullNick.java | 159 +++ .../f00f/net/irc/martyr/util/IRCStringUtils.java | 90 ++ .../net/irc/martyr/util/ParameterIterator.java | 124 +++ EssentialsUpdate/src/plugin.yml | 21 + 160 files changed, 12474 insertions(+) create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsUpdate.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/GetFile.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/ModuleInfo.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/PastieUpload.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/PostToUrl.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/UpdateCheck.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/UpdateFile.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/UpdateProcess.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/UpdatesDownloader.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/Version.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/VersionInfo.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/states/Modules.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/ClientStateMonitor.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/Command.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/CommandObserver.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/CommandRegister.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/CommandSender.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/CronManager.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/ForwardObservable.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/GenericAutoService.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/GenericCommandAutoService.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/IRCConnection.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/InCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/InputHandler.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/OutCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/State.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/StateObserver.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/TimerTaskCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/ActionCtcp.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/ChannelModeCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpMessage.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpNotice.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/InviteCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/IsonCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/JoinCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/KickCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/MessageCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/ModeCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/NamesCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/NickCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/NoticeCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/PartCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/PassCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/PingCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/PongCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/QuitCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/RawCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/TopicCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/UnknownCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserModeCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/WelcomeCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/WhoisCommand.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/AlreadyRegisteredError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/CannotSendToChanError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/CantKillServerError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChanOPrivsNeededError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelBannedError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelInviteOnlyError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelLimitError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelWrongKeyError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ErroneusNicknameError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/FileErrorError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericJoinError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/KeySetError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/LoadTooHighError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NeedMoreParamsError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickCollisionError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickInUseError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoAdminInfoError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoLoginError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoMotdError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoNicknameGivenError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOperHostError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOriginError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPermForHostError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPrivilegesError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoRecipientError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchChannelError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchNickError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchServerError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTextToSendError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTopLevelError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotOnChannelError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotRegisteredError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/PasswdMismatchError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/SummonDisabledError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyChannelsError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyTargetsError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UModeUnknownFlagError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownCommandError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownModeError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserNotInChannelError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserOnChannelError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDisabledError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDontMatchError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/WasNoSuchNickError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/WildTopLevelError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/YoureBannedCreepError.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/GenericMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/README create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/AnonChannelMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/BanMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ExceptionMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMask.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteMaskMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteOnlyMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/KeyMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/LimitMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ModeratedMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/NoExtMsgMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/OperMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/PrivateMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/SecretMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/TopicLockMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/VoiceMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/GenericUserMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/InvisibleMode.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/AbstractWhoisReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/AwayReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ChannelCreationReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericStringReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserClientReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserMeReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserOpReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListEndReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListStartReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ModeReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesEndReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/NowAwayReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/TopicInfoReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnAwayReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnknownReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisChannelsReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisEndReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisIdleReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisServerReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisUserReply.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoJoin.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoReconnect.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoRegister.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoResponder.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/util/CtcpUtil.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/util/FullNick.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/util/IRCStringUtils.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/util/ParameterIterator.java create mode 100644 EssentialsUpdate/src/plugin.yml (limited to 'EssentialsUpdate/src') diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java b/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java new file mode 100644 index 000000000..5b134b8b8 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java @@ -0,0 +1,601 @@ +package com.earth2me.essentials.update; + +import f00f.net.irc.martyr.GenericAutoService; +import f00f.net.irc.martyr.IRCConnection; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.Member; +import f00f.net.irc.martyr.commands.InviteCommand; +import f00f.net.irc.martyr.commands.KickCommand; +import f00f.net.irc.martyr.commands.MessageCommand; +import f00f.net.irc.martyr.commands.NoticeCommand; +import f00f.net.irc.martyr.commands.QuitCommand; +import f00f.net.irc.martyr.commands.TopicCommand; +import f00f.net.irc.martyr.errors.GenericJoinError; +import f00f.net.irc.martyr.services.AutoJoin; +import f00f.net.irc.martyr.services.AutoReconnect; +import f00f.net.irc.martyr.services.AutoRegister; +import f00f.net.irc.martyr.services.AutoResponder; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.Enumeration; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Priority; +import org.bukkit.event.Event.Type; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; + + +public class EssentialsHelp extends PlayerListener +{ + private transient Player chatUser; + private transient IRCConnection connection; + private transient AutoReconnect autoReconnect; + private transient boolean shouldQuit = false; + private final transient Server server; + private final transient Plugin plugin; + private final static Charset UTF8 = Charset.forName("utf-8"); + + public EssentialsHelp(Plugin plugin) + { + this.plugin = plugin; + this.server = plugin.getServer(); + } + + public void registerEvents() + { + final PluginManager pluginManager = server.getPluginManager(); + pluginManager.registerEvent(Type.PLAYER_QUIT, this, Priority.Low, plugin); + pluginManager.registerEvent(Type.PLAYER_CHAT, this, Priority.Low, plugin); + } + + public void onCommand(CommandSender sender) + { + if (sender instanceof Player && sender.hasPermission("essentials.helpchat")) + { + if (chatUser == null) + { + chatUser = (Player)sender; + connection = null; + sender.sendMessage("You will be connected to the Essentials Help Chat."); + sender.sendMessage("All your chat messages will be forwarded to the channel. You can't chat with other players on your server while in help chat, but you can use commands."); + sender.sendMessage("Please be patient, if noone is available, check back later."); + sender.sendMessage("Type !help to get a list of all commands."); + sender.sendMessage("Type !quit to leave the channel."); + sender.sendMessage("Do you want to join the channel now? (yes/no)"); + } + if (!chatUser.equals(sender)) + { + sender.sendMessage("The player " + chatUser.getDisplayName() + " is already using the essentialshelp."); + } + } + else + { + sender.sendMessage("Please run the command as op from in game."); + } + } + + public void onDisable() + { + if (autoReconnect != null && connection != null) + { + autoReconnect.disable(); + shouldQuit = true; + connection.disconnect(); + } + } + + private void sendChatMessage(final Player player, final String message) + { + final String messageCleaned = message.trim(); + if (messageCleaned.isEmpty()) + { + return; + } + if (connection == null) + { + if (messageCleaned.equalsIgnoreCase("yes")) + { + player.sendMessage("Connecting..."); + connectToIRC(player); + } + if (messageCleaned.equalsIgnoreCase("no") || message.equalsIgnoreCase("!quit")) + { + chatUser = null; + } + } + else + { + final String lowMessage = messageCleaned.toLowerCase(); + if (lowMessage.startsWith("!quit")) + { + chatUser = null; + autoReconnect.disable(); + shouldQuit = true; + connection.sendCommand(new QuitCommand("Connection closed by user.")); + player.sendMessage("Connection closed."); + return; + } + if (!connection.getClientState().getChannels().hasMoreElements()) + { + player.sendMessage("Not connected yet!"); + return; + } + if (lowMessage.startsWith("!list")) + { + final Enumeration members = ((Channel)connection.getClientState().getChannels().nextElement()).getMembers(); + final StringBuilder sb = new StringBuilder(); + while (members.hasMoreElements()) + { + if (sb.length() > 0) + { + sb.append("§f, "); + } + final Member member = (Member)members.nextElement(); + if (member.hasOps() || member.hasVoice()) + { + sb.append("§6"); + } + else + { + sb.append("§7"); + } + sb.append(member.getNick()); + } + player.sendMessage(sb.toString()); + return; + } + if (lowMessage.startsWith("!help")) + { + player.sendMessage("Commands: (Note: Files send to the chat will be public viewable.)"); + player.sendMessage("!errors - Send the last server errors to the chat."); + player.sendMessage("!startup - Send the last startup messages to the chat."); + player.sendMessage("!config - Sends your Essentials config to the chat."); + player.sendMessage("!list - List all players in chat."); + player.sendMessage("!quit - Leave chat."); + return; + } + if (lowMessage.startsWith("!errors")) + { + sendErrors(); + return; + } + if (lowMessage.startsWith("!startup")) + { + sendStartup(); + return; + } + if (lowMessage.startsWith("!config")) + { + sendConfig(); + return; + } + final Channel channel = (Channel)connection.getClientState().getChannels().nextElement(); + connection.sendCommand(new MessageCommand(channel.getName(), messageCleaned)); + chatUser.sendMessage("§6" + connection.getClientState().getNick().getNick() + ": §7" + messageCleaned); + } + } + + private void connectToIRC(final Player player) + { + connection = new IRCConnection(); + // Required services + new AutoResponder(connection); + int versionNumber = 0; + final StringBuilder nameBuilder = new StringBuilder(); + nameBuilder.append(player.getName()); + + final Matcher versionMatch = Pattern.compile("git-Bukkit-([0-9]+).([0-9]+).([0-9]+)-[0-9]+-[0-9a-z]+-b([0-9]+)jnks.*").matcher(server.getVersion()); + if (versionMatch.matches()) + { + nameBuilder.append(" CB"); + nameBuilder.append(versionMatch.group(4)); + } + + final Plugin essentials = server.getPluginManager().getPlugin("Essentials"); + if (essentials != null) + { + nameBuilder.append(" ESS"); + nameBuilder.append(essentials.getDescription().getVersion()); + } + + final Plugin groupManager = server.getPluginManager().getPlugin("GroupManager"); + if (groupManager != null) + { + nameBuilder.append(" GM"); + if (!groupManager.isEnabled()) + { + nameBuilder.append('!'); + } + } + + final Plugin pex = server.getPluginManager().getPlugin("PermissionsEx"); + if (pex != null) + { + nameBuilder.append(" PEX"); + if (!pex.isEnabled()) + { + nameBuilder.append('!'); + } + nameBuilder.append(pex.getDescription().getVersion()); + } + + final Plugin pb = server.getPluginManager().getPlugin("PermissionsBukkit"); + if (pb != null) + { + nameBuilder.append(" PB"); + if (!pb.isEnabled()) + { + nameBuilder.append('!'); + } + nameBuilder.append(pb.getDescription().getVersion()); + } + + final Plugin bp = server.getPluginManager().getPlugin("bPermissions"); + if (bp != null) + { + nameBuilder.append(" BP"); + if (!bp.isEnabled()) + { + nameBuilder.append('!'); + } + nameBuilder.append(bp.getDescription().getVersion()); + } + + final Plugin perm = server.getPluginManager().getPlugin("Permissions"); + if (perm != null) + { + nameBuilder.append(" P"); + if (!perm.isEnabled()) + { + nameBuilder.append('!'); + } + nameBuilder.append(perm.getDescription().getVersion()); + } + + new AutoRegister(connection, "Ess_" + player.getName(), "esshelp", nameBuilder.toString()); + + autoReconnect = new AutoReconnect(connection); + new KickAutoJoin(connection, "#essentials"); + + new IRCListener(connection); + autoReconnect.go("irc.esper.net", 6667); + } + + private void handleIRCmessage(final String nick, final String message) + { + + if (chatUser != null) + { + final StringBuilder sb = new StringBuilder(); + sb.append("§6"); + sb.append(nick); + sb.append(": §7"); + final String coloredmessage = message.replace("\u000300", "§f").replace("\u000301", "§0").replace("\u000302", "§1").replace("\u000303", "§2").replace("\u000304", "§c").replace("\u000305", "§4").replace("\u000306", "§5").replace("\u000307", "§6").replace("\u000308", "§e").replace("\u000309", "§a").replace("\u00030", "§f").replace("\u000310", "§b").replace("\u000311", "§f").replace("\u000312", "§9").replace("\u000313", "§d").replace("\u000314", "§8").replace("\u000315", "§7").replace("\u00031", "§0").replace("\u00032", "§1").replace("\u00033", "§2").replace("\u00034", "§c").replace("\u00035", "§4").replace("\u00036", "§5").replace("\u00037", "§6").replace("\u00038", "§e").replace("\u00039", "§a").replace("\u0003", "§7"); + sb.append(coloredmessage); + chatUser.sendMessage(sb.toString()); + } + } + + private void sendErrors() + { + BufferedReader page = null; + try + { + File bukkitFolder = plugin.getDataFolder().getAbsoluteFile().getParentFile().getParentFile(); + if (bukkitFolder == null || !bukkitFolder.exists()) + { + chatUser.sendMessage("Bukkit folder not found."); + return; + } + File logFile = new File(bukkitFolder, "server.log"); + if (!logFile.exists()) + { + chatUser.sendMessage("Server log not found."); + return; + } + FileInputStream fis = new FileInputStream(logFile); + if (logFile.length() > 1000000) + { + fis.skip(logFile.length()-1000000); + } + page = new BufferedReader(new InputStreamReader(fis)); + final StringBuilder input = new StringBuilder(); + String line; + Pattern pattern = Pattern.compile("^[0-9 :-]+\\[INFO\\].*"); + while ((line = page.readLine()) != null) + { + if (!pattern.matcher(line).matches()) { + input.append(line).append("\n"); + } + } + if (input.length()>10000) { + input.delete(0, input.length()-10000); + } + final PastieUpload pastie = new PastieUpload(); + final String url = pastie.send(input.toString()); + final Channel channel = (Channel)connection.getClientState().getChannels().nextElement(); + String message = "Errors: " + url; + chatUser.sendMessage("§6" + connection.getClientState().getNick().getNick() + ": §7" + message); + connection.sendCommand(new MessageCommand(channel.getName(), message)); + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, null, ex); + chatUser.sendMessage(ex.getMessage()); + } + finally + { + try + { + if (page != null) + { + page.close(); + } + } + catch (IOException ex) + { + Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + private void sendStartup() + { + BufferedReader page = null; + try + { + File bukkitFolder = plugin.getDataFolder().getAbsoluteFile().getParentFile().getParentFile(); + if (bukkitFolder == null || !bukkitFolder.exists()) + { + chatUser.sendMessage("Bukkit folder not found."); + return; + } + File logFile = new File(bukkitFolder, "server.log"); + if (!logFile.exists()) + { + chatUser.sendMessage("Server log not found."); + return; + } + FileInputStream fis = new FileInputStream(logFile); + if (logFile.length() > 1000000) + { + fis.skip(logFile.length()-1000000); + } + page = new BufferedReader(new InputStreamReader(fis)); + final StringBuilder input = new StringBuilder(); + String line; + Pattern patternStart = Pattern.compile("^[0-9 :-]+\\[INFO\\] Starting minecraft server version.*"); + Pattern patternEnd = Pattern.compile("^[0-9 :-]+\\[INFO\\] Done \\([0-9.,]+s\\)! For help, type \"help\".*"); + boolean log = false; + while ((line = page.readLine()) != null) + { + if (patternStart.matcher(line).matches()) { + if (input.length() > 0) { + input.delete(0, input.length()); + } + log = true; + } + if (log) { + input.append(line).append("\n"); + } + if (patternEnd.matcher(line).matches()) { + log = false; + } + } + if (input.length()>10000) { + input.delete(0, input.length()-10000); + } + final PastieUpload pastie = new PastieUpload(); + final String url = pastie.send(input.toString()); + final Channel channel = (Channel)connection.getClientState().getChannels().nextElement(); + String message = "Startup: " + url; + chatUser.sendMessage("§6" + connection.getClientState().getNick().getNick() + ": §7" + message); + connection.sendCommand(new MessageCommand(channel.getName(), message)); + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, null, ex); + chatUser.sendMessage(ex.getMessage()); + } + finally + { + try + { + if (page != null) + { + page.close(); + } + } + catch (IOException ex) + { + Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + private void sendConfig() + { + BufferedReader page = null; + try + { + File configFolder = new File(plugin.getDataFolder().getParentFile(), "Essentials"); + if (!configFolder.exists()) + { + chatUser.sendMessage("Essentials plugin folder not found."); + return; + } + File configFile = new File(configFolder, "config.yml"); + if (!configFile.exists()) + { + chatUser.sendMessage("Essentials config file not found."); + return; + } + page = new BufferedReader(new InputStreamReader(new FileInputStream(configFile), UTF8)); + final StringBuilder input = new StringBuilder(); + String line; + while ((line = page.readLine()) != null) + { + input.append(line).append("\n"); + } + final PastieUpload pastie = new PastieUpload(); + final String url = pastie.send(input.toString()); + final Channel channel = (Channel)connection.getClientState().getChannels().nextElement(); + String message = "Essentials config.yml: " + url; + chatUser.sendMessage("§6" + connection.getClientState().getNick().getNick() + ": §7" + message); + connection.sendCommand(new MessageCommand(channel.getName(), message)); + + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, null, ex); + chatUser.sendMessage(ex.getMessage()); + } + finally + { + try + { + if (page != null) + { + page.close(); + } + } + catch (IOException ex) + { + Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + @Override + public void onPlayerChat(PlayerChatEvent event) + { + if (event.getPlayer() == chatUser) + { + sendChatMessage(event.getPlayer(), event.getMessage()); + event.setCancelled(true); + return; + } + } + + @Override + public void onPlayerQuit(PlayerQuitEvent event) + { + chatUser = null; + if (autoReconnect != null) + { + autoReconnect.disable(); + } + shouldQuit = true; + if (connection != null) + { + connection.sendCommand(new QuitCommand("Connection closed by user.")); + } + return; + } + + + class KickAutoJoin extends AutoJoin + { + private String channel; + + public KickAutoJoin(IRCConnection connection, String channel) + { + super(connection, channel); + this.channel = channel; + } + + @Override + protected void updateCommand(InCommand command_o) + { + if (command_o instanceof KickCommand) + { + final KickCommand kickCommand = (KickCommand)command_o; + + if (kickCommand.kickedUs(getConnection().getClientState())) + { + if (Channel.areEqual(kickCommand.getChannel(), channel)) + { + chatUser.sendMessage("You have been kicked from the channel: " + kickCommand.getComment()); + chatUser = null; + autoReconnect.disable(); + shouldQuit = true; + connection.sendCommand(new QuitCommand("Connection closed by user.")); + } + } + } + else if (command_o instanceof GenericJoinError) + { + GenericJoinError joinErr = (GenericJoinError)command_o; + + if (Channel.areEqual(joinErr.getChannel(), channel)) + { + scheduleJoin(); + } + } + else if (command_o instanceof InviteCommand) + { + InviteCommand invite = (InviteCommand)command_o; + if (!getConnection().getClientState().isOnChannel(invite.getChannel())) + { + performJoin(); + } + } + } + } + + + class IRCListener extends GenericAutoService + { + public IRCListener(final IRCConnection connection) + { + super(connection); + enable(); + } + + @Override + protected void updateState(final State state) + { + if (state == State.UNCONNECTED && shouldQuit) + { + connection = null; + shouldQuit = false; + } + } + + @Override + protected void updateCommand(final InCommand command) + { + if (command instanceof MessageCommand) + { + final MessageCommand msg = (MessageCommand)command; + EssentialsHelp.this.handleIRCmessage(msg.getSource().getNick(), msg.getMessage()); + } + if (command instanceof TopicCommand) + { + final TopicCommand msg = (TopicCommand)command; + EssentialsHelp.this.handleIRCmessage(msg.getChannel(), msg.getTopic()); + } + if (command instanceof NoticeCommand) + { + final NoticeCommand msg = (NoticeCommand)command; + EssentialsHelp.this.handleIRCmessage(msg.getFrom().getNick(), msg.getNotice()); + } + } + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsUpdate.java b/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsUpdate.java new file mode 100644 index 000000000..d4ee6c0fc --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsUpdate.java @@ -0,0 +1,66 @@ +package com.earth2me.essentials.update; + +import com.earth2me.essentials.update.UpdateCheck.CheckResult; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.java.JavaPlugin; + + +public class EssentialsUpdate extends JavaPlugin +{ + private transient EssentialsHelp essentialsHelp; + private transient UpdateProcess updateProcess; + + @Override + public void onEnable() + { + if (!getDataFolder().exists() && !getDataFolder().mkdirs() ) { + Bukkit.getLogger().severe("Could not create data folder:"+getDataFolder().getPath()); + } + essentialsHelp = new EssentialsHelp(this); + essentialsHelp.registerEvents(); + + final UpdateCheck updateCheck = new UpdateCheck(this); + updateProcess = new UpdateProcess(this, updateCheck); + updateProcess.registerEvents(); + + Bukkit.getLogger().info("EssentialsUpdate " + getDescription().getVersion() + " loaded."); + + if (updateCheck.isEssentialsInstalled()) + { + updateCheck.checkForUpdates(); + final Version myVersion = new Version(getDescription().getVersion()); + if (updateCheck.getResult() == CheckResult.NEW_ESS && myVersion.equals(updateCheck.getNewVersion())) + { + Bukkit.getLogger().info("Versions of EssentialsUpdate and Essentials do not match. Starting automatic update."); + updateProcess.doAutomaticUpdate(); + } + updateCheck.scheduleUpdateTask(); + } + else + { + Bukkit.getLogger().info("Essentials is ready for installation. Join the game and follow the instructions."); + } + } + + @Override + public void onDisable() + { + essentialsHelp.onDisable(); + } + + @Override + public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) + { + if (command.getName().equalsIgnoreCase("essentialsupdate")) + { + updateProcess.onCommand(sender); + } + if (command.getName().equalsIgnoreCase("essentialshelp")) + { + essentialsHelp.onCommand(sender); + } + return true; + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/GetFile.java b/EssentialsUpdate/src/com/earth2me/essentials/update/GetFile.java new file mode 100644 index 000000000..888950f34 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/GetFile.java @@ -0,0 +1,112 @@ +package com.earth2me.essentials.update; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.logging.Logger; + + +public class GetFile +{ + private transient URLConnection connection; + private transient MessageDigest digest; + + public GetFile(final String urlString) throws MalformedURLException, IOException + { + final URL url = new URL(urlString); + this.connection = url.openConnection(); + this.connection.setConnectTimeout(1000); + this.connection.setReadTimeout(5000); + this.connection.setUseCaches(false); + this.connection.connect(); + final int respCode = ((HttpURLConnection)this.connection).getResponseCode(); + if (respCode >= 300 && respCode < 400 && this.connection.getHeaderField("Location") != null) + { + connection.getInputStream().close(); + final URL redirect = new URL(this.connection.getHeaderField("Location")); + this.connection = redirect.openConnection(); + this.connection.setConnectTimeout(1000); + this.connection.setReadTimeout(5000); + this.connection.setUseCaches(false); + this.connection.connect(); + } + } + + public void saveTo(final File file) throws IOException + { + try + { + saveTo(file, null); + } + catch (NoSuchAlgorithmException ex) + { + // Ignore because the code is never called + } + } + + public void saveTo(final File file, final String key) throws IOException, NoSuchAlgorithmException + { + if (key != null) + { + digest = MessageDigest.getInstance("SHA256"); + } + final byte[] buffer = new byte[1024 * 8]; + boolean brokenFile = false; + final BufferedInputStream input = new BufferedInputStream(connection.getInputStream()); + try + { + final BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(file)); + try + { + int length; + do + { + length = input.read(buffer); + if (length >= 0) + { + if (key != null) + { + digest.update(buffer, 0, length); + } + output.write(buffer, 0, length); + } + } + while (length >= 0); + if (key != null) + { + final byte[] checksum = digest.digest(); + final String checksumString = new BigInteger(checksum).toString(36); + if (!checksumString.equals(key)) + { + brokenFile = true; + } + } + } + finally + { + output.close(); + } + if (brokenFile && !file.delete()) + { + Logger.getLogger("Minecraft").severe("Could not delete file " + file.getPath()); + } + } + finally + { + input.close(); + } + if (brokenFile) + { + throw new IOException("Checksum check failed."); + } + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/ModuleInfo.java b/EssentialsUpdate/src/com/earth2me/essentials/update/ModuleInfo.java new file mode 100644 index 000000000..722fca3e1 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/ModuleInfo.java @@ -0,0 +1,35 @@ +package com.earth2me.essentials.update; + +import java.net.MalformedURLException; +import java.net.URL; +import org.bukkit.configuration.Configuration; + + +public class ModuleInfo +{ + private final transient String url; + private final transient String version; + private final transient String hash; + + public ModuleInfo(final Configuration updateConfig, final String path) + { + url = updateConfig.getString(path + ".url", null); + version = updateConfig.getString(path + ".version", null); + hash = updateConfig.getString(path + ".hash", null); + } + + public URL getUrl() throws MalformedURLException + { + return new URL(url); + } + + public String getVersion() + { + return version; + } + + public String getHash() + { + return hash; + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/PastieUpload.java b/EssentialsUpdate/src/com/earth2me/essentials/update/PastieUpload.java new file mode 100644 index 000000000..6cad44e4d --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/PastieUpload.java @@ -0,0 +1,40 @@ +package com.earth2me.essentials.update; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class PastieUpload +{ + private final transient PostToUrl connection; + + public PastieUpload() throws MalformedURLException + { + connection = new PostToUrl(new URL("http://pastie.org/pastes")); + } + + public String send(final String data) throws IOException + { + final Map map = new HashMap(); + map.put("paste[parser_id]", "19"); + map.put("paste[authorization]", "burger"); + map.put("paste[body]", data); + map.put("paste[restricted]", "1"); + final String html = connection.send(map); + final Matcher matcher = Pattern.compile("(?s).*\\?key=([a-z0-9]+).*").matcher(html); + if (matcher.matches()) + { + final String key = matcher.group(1); + return "http://pastie.org/private/" + key; + } + else + { + throw new IOException("Failed to upload to pastie.org"); + } + } +} \ No newline at end of file diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/PostToUrl.java b/EssentialsUpdate/src/com/earth2me/essentials/update/PostToUrl.java new file mode 100644 index 000000000..c8978961b --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/PostToUrl.java @@ -0,0 +1,66 @@ +package com.earth2me.essentials.update; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.math.BigInteger; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; +import java.util.Map; +import java.util.Random; + + +public class PostToUrl +{ + private final transient URL url; + private final transient String boundary; + private final transient Random random = new Random(); + private final static String CRLF = "\r\n"; + private final static Charset UTF8 = Charset.forName("utf-8"); + + public PostToUrl(final URL url) + { + this.url = url; + final byte[] bytes = new byte[32]; + random.nextBytes(bytes); + this.boundary = "----------" + new BigInteger(bytes).toString(Character.MAX_RADIX) + "_$"; + } + + public String send(final Map data) throws IOException + { + final URLConnection connection = url.openConnection(); + connection.setRequestProperty("content-type", "multipart/form-data; boundary=" + boundary); + final StringBuilder dataBuilder = new StringBuilder(); + for (Map.Entry entry : data.entrySet()) + { + if (entry.getValue() instanceof String) + { + dataBuilder.append("--").append(boundary).append(CRLF); + dataBuilder.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append('"').append(CRLF); + dataBuilder.append(CRLF); + dataBuilder.append(entry.getValue()).append(CRLF); + } + // TODO: Add support for file upload + } + dataBuilder.append("--").append(boundary).append("--").append(CRLF); + dataBuilder.append(CRLF); + connection.setDoOutput(true); + final byte[] message = dataBuilder.toString().getBytes(UTF8); + connection.setRequestProperty("content-length", Integer.toString(message.length)); + connection.connect(); + final OutputStream stream = connection.getOutputStream(); + stream.write(message); + stream.close(); + final BufferedReader page = new BufferedReader(new InputStreamReader(connection.getInputStream(), UTF8)); + final StringBuilder input = new StringBuilder(); + String line; + while ((line = page.readLine()) != null) + { + input.append(line).append("\n"); + } + page.close(); + return input.toString(); + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateCheck.java b/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateCheck.java new file mode 100644 index 000000000..dcda252a0 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateCheck.java @@ -0,0 +1,203 @@ +package com.earth2me.essentials.update; + +import java.io.File; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; + + +public class UpdateCheck +{ + private transient CheckResult result = CheckResult.UNKNOWN; + private transient Version currentVersion; + private transient Version newVersion = null; + private transient int bukkitResult = 0; + private transient UpdateFile updateFile; + private final static int CHECK_INTERVAL = 20 * 60 * 60 * 6; + private final transient Plugin plugin; + private transient boolean essentialsInstalled; + + public UpdateCheck(Plugin plugin) + { + this.plugin = plugin; + updateFile = new UpdateFile(plugin); + checkForEssentials(); + } + + private void checkForEssentials() + { + PluginManager pm = plugin.getServer().getPluginManager(); + Plugin essentials = pm.getPlugin("Essentials"); + if (essentials == null) + { + essentialsInstalled = false; + if (new File(plugin.getDataFolder().getParentFile(), "Essentials.jar").exists()) + { + Bukkit.getLogger().severe("Essentials.jar found, but not recognized by Bukkit. Broken download?"); + } + } + else + { + essentialsInstalled = true; + currentVersion = new Version(essentials.getDescription().getVersion()); + } + } + + public void scheduleUpdateTask() + { + plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() + { + @Override + public void run() + { + updateFile = new UpdateFile(plugin); + checkForUpdates(); + } + }, CHECK_INTERVAL, CHECK_INTERVAL); + } + + public boolean isEssentialsInstalled() + { + return essentialsInstalled; + } + + public CheckResult getResult() + { + return result; + } + + int getNewBukkitVersion() + { + return bukkitResult; + } + + VersionInfo getNewVersionInfo() + { + return updateFile.getVersions().get(newVersion); + } + + public enum CheckResult + { + NEW_ESS, NEW_ESS_BUKKIT, NEW_BUKKIT, OK, UNKNOWN + } + + public void checkForUpdates() + { + if (currentVersion == null) + { + return; + } + final Map versions = updateFile.getVersions(); + final int bukkitVersion = getBukkitVersion(); + Version higher = null; + Version found = null; + Version lower = null; + int bukkitHigher = 0; + int bukkitLower = 0; + for (Entry entry : versions.entrySet()) + { + final int minBukkit = entry.getValue().getMinBukkit(); + final int maxBukkit = entry.getValue().getMaxBukkit(); + if (minBukkit == 0 || maxBukkit == 0) + { + continue; + } + if (bukkitVersion <= maxBukkit) + { + if (bukkitVersion < minBukkit) + { + if (higher == null || higher.compareTo(entry.getKey()) < 0) + { + + higher = entry.getKey(); + bukkitHigher = minBukkit; + } + } + else + { + if (found == null || found.compareTo(entry.getKey()) < 0) + { + found = entry.getKey(); + } + } + } + else + { + if (lower == null || lower.compareTo(entry.getKey()) < 0) + { + lower = entry.getKey(); + bukkitLower = minBukkit; + } + } + } + if (found != null) + { + if (found.compareTo(currentVersion) > 0) + { + result = CheckResult.NEW_ESS; + newVersion = found; + } + else + { + result = CheckResult.OK; + } + } + else if (higher != null) + { + if (higher.compareTo(currentVersion) > 0) + { + newVersion = higher; + result = CheckResult.NEW_ESS_BUKKIT; + bukkitResult = bukkitHigher; + } + else if (higher.compareTo(currentVersion) < 0) + { + result = CheckResult.UNKNOWN; + } + else + { + result = CheckResult.NEW_BUKKIT; + bukkitResult = bukkitHigher; + } + } + else if (lower != null) + { + if (lower.compareTo(currentVersion) > 0) + { + result = CheckResult.NEW_ESS_BUKKIT; + newVersion = lower; + bukkitResult = bukkitLower; + } + else if (lower.compareTo(currentVersion) < 0) + { + result = CheckResult.UNKNOWN; + } + else + { + result = CheckResult.NEW_BUKKIT; + bukkitResult = bukkitLower; + } + } + + } + + private int getBukkitVersion() + { + final Matcher versionMatch = Pattern.compile("git-Bukkit-([0-9]+).([0-9]+).([0-9]+)-[0-9]+-[0-9a-z]+-b([0-9]+)jnks.*").matcher(plugin.getServer().getVersion()); + if (versionMatch.matches()) + { + return Integer.parseInt(versionMatch.group(4)); + } + throw new NumberFormatException("Bukkit Version changed!"); + } + + public Version getNewVersion() + { + return newVersion; + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateFile.java b/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateFile.java new file mode 100644 index 000000000..8f34bffc4 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateFile.java @@ -0,0 +1,204 @@ +package com.earth2me.essentials.update; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.Signature; +import java.security.spec.X509EncodedKeySpec; +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.plugin.Plugin; +import org.bukkit.configuration.file.YamlConfiguration; + + +public class UpdateFile +{ + private final static Logger LOGGER = Logger.getLogger("Minecraft"); + private final static String UPDATE_URL = "http://goo.gl/67jev"; + private final static BigInteger PUBLIC_KEY = new BigInteger("5ha6a2d4qdy17ttkg8evh74sl5a87djojwenu12k1lvy8ui6003e6l06rntczpoh99mhc3txj8mqlxw111oyy9yl7s7qpyluyzix3j1odxrxx4u52gxvyu6qiteapczkzvi7rxgeqsozz7b19rdx73a7quo9ybwpz1cr82r7x5k0pg2a73pjjsv2j1awr13azo7klrcxp9y5xxwf5qv1s3tw4zqftli18u0ek5qkbzfbgk1v5n2f11pkwwk6p0mibrn26wnjbv11vyiqgu95o7busmt6vf5q7grpcenl637w83mbin56s3asj1131b2mscj9xep3cbj7la9tgsxl5bj87vzy8sk2d34kzwqdqgh9nry43nqqus12l1stmiv184r8r3jcy8w43e8h1u1mzklldb5eytkuhayqik8l3ns04hwt8sgacvw534be8sx26qrn5s1", 36); + private final transient File file; + private transient YamlConfiguration updateConfig; + private final transient Plugin plugin; + private final transient TreeMap versions = new TreeMap(); + + public UpdateFile(final Plugin plugin) + { + this.plugin = plugin; + final long lastUpdate = Long.parseLong(plugin.getConfig().getString("lastupdate", "0")); + file = new File(plugin.getDataFolder(), "update.yml"); + if (lastUpdate < System.currentTimeMillis() - 1000 * 60 * 60 * 6 || !file.exists()) + { + if (file.exists() && !file.delete()) + { + LOGGER.log(Level.SEVERE, "Could not delete file update.yml!"); + return; + } + if (!downloadFile() || !checkFile()) + { + LOGGER.log(Level.SEVERE, "Could not download and verify file update.yml!"); + return; + } + } + try + { + readVersions(); + } + catch (Exception ex) + { + LOGGER.log(Level.SEVERE, "Could not load update.yml!"); + return; + } + } + + private boolean downloadFile() + { + GetFile getFile; + try + { + getFile = new GetFile(UPDATE_URL); + getFile.saveTo(file); + plugin.getConfig().set("lastupdate", System.currentTimeMillis()); + plugin.getConfig().save(new File(plugin.getDataFolder(),"config.yml")); + return true; + } + catch (IOException ex) + { + LOGGER.log(Level.SEVERE, "Error while downloading update.yml", ex); + return false; + } + } + + private boolean checkFile() + { + BufferedInputStream bis = null; + try + { + bis = new BufferedInputStream(new FileInputStream(file)); + if (bis.read() != '#') + { + throw new IOException("File has to start with #"); + } + final StringBuilder length = new StringBuilder(); + final StringBuilder signature = new StringBuilder(); + boolean isSignature = false; + do + { + final int cur = bis.read(); + if (cur == -1) + { + break; + } + if (cur == ':') + { + isSignature = true; + } + else if (cur == '\n') + { + break; + } + else if ((cur >= '0' && cur <= '9') + || (cur >= 'a' && cur <= 'z')) + { + if (isSignature) + { + signature.append((char)cur); + } + else + { + length.append((char)cur); + } + } + else + { + throw new IOException("Illegal character in signature!"); + } + } + while (true); + if (length.length() == 0 || signature.length() == 0) + { + throw new IOException("Broken signature!"); + } + final int sigLength = new BigInteger(length.toString(), 36).intValue(); + if (sigLength < 0 || sigLength > 2048) + { + throw new IOException("Invalid signature length!"); + } + final byte[] sigBytes = new BigInteger(signature.toString(), 36).toByteArray(); + if (sigLength < sigBytes.length) + { + throw new IOException("Length is less then available bytes."); + } + byte[] realBytes; + if (sigLength == sigBytes.length) + { + realBytes = sigBytes; + } + else + { + realBytes = new byte[sigLength]; + System.arraycopy(sigBytes, 0, realBytes, sigLength - sigBytes.length, sigBytes.length); + } + final X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(PUBLIC_KEY.toByteArray()); + final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + final PublicKey pubKey = keyFactory.generatePublic(pubKeySpec); + final Signature rsa = Signature.getInstance("SHA256withRSA"); + rsa.initVerify(pubKey); + final byte[] buffer = new byte[2048]; + int readLength; + do + { + readLength = bis.read(buffer); + if (readLength >= 0) + { + rsa.update(buffer, 0, readLength); + } + } + while (readLength >= 0); + return rsa.verify(realBytes); + } + catch (Exception ex) + { + LOGGER.log(Level.SEVERE, ex.getMessage(), ex); + } + finally + { + try + { + if (bis != null) + { + bis.close(); + } + } + catch (IOException ex) + { + LOGGER.log(Level.SEVERE, ex.getMessage(), ex); + } + } + return false; + } + + private void readVersions() throws Exception + { + updateConfig = new YamlConfiguration(); + updateConfig.load(file); + versions.clear(); + for (String versionString : updateConfig.getKeys(false)) + { + final Version version = new Version(versionString); + final VersionInfo info = new VersionInfo(updateConfig, versionString); + versions.put(version, info); + } + } + + public Map getVersions() + { + return Collections.unmodifiableMap(versions.descendingMap()); + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateProcess.java b/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateProcess.java new file mode 100644 index 000000000..95898bcb6 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/UpdateProcess.java @@ -0,0 +1,128 @@ +package com.earth2me.essentials.update; + +import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Priority; +import org.bukkit.event.Event.Type; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; + + +public class UpdateProcess extends PlayerListener +{ + private transient Player currentPlayer; + private final transient Plugin plugin; + private final transient UpdateCheck updateCheck; + + public UpdateProcess(final Plugin plugin, final UpdateCheck updateCheck) + { + this.plugin = plugin; + this.updateCheck = updateCheck; + } + + public void registerEvents() + { + final PluginManager pluginManager = plugin.getServer().getPluginManager(); + pluginManager.registerEvent(Type.PLAYER_QUIT, this, Priority.Low, plugin); + pluginManager.registerEvent(Type.PLAYER_CHAT, this, Priority.Lowest, plugin); + } + + @Override + public void onPlayerChat(final PlayerChatEvent event) + { + if (event.getPlayer() == currentPlayer) + { + reactOnMessage(event.getMessage()); + event.setCancelled(true); + return; + } + } + + @Override + public void onPlayerJoin(final PlayerJoinEvent event) + { + final Player player = event.getPlayer(); + if (player.hasPermission("essentials.update") && !updateCheck.isEssentialsInstalled()) + { + player.sendMessage("Hello " + player.getDisplayName()); + player.sendMessage("Please type /essentialsupdate into the chat to start the installation of Essentials."); + } + if (player.hasPermission("essentials.update")) + { + final UpdateCheck.CheckResult result = updateCheck.getResult(); + switch (result) + { + case NEW_ESS: + player.sendMessage("The new version " + updateCheck.getNewVersion().toString() + " for Essentials is available. Please type /essentialsupdate to update."); + break; + case NEW_BUKKIT: + player.sendMessage("Your bukkit version is not the recommended build for Essentials, please update to version " + updateCheck.getNewBukkitVersion() + "."); + break; + case NEW_ESS_BUKKIT: + player.sendMessage("There is a new version " + updateCheck.getNewVersion().toString() + " of Essentials for Bukkit " + updateCheck.getNewBukkitVersion()); + break; + default: + } + } + } + + void doAutomaticUpdate() + { + final UpdatesDownloader downloader = new UpdatesDownloader(); + final VersionInfo info = updateCheck.getNewVersionInfo(); + final List changelog = info.getChangelog(); + Bukkit.getLogger().info("Essentials changelog " + updateCheck.getNewVersion().toString()); + for (String line : changelog) + { + Bukkit.getLogger().info(" - "+line); + } + downloader.start(plugin.getServer().getUpdateFolderFile(), info); + } + + void doManualUpdate() + { + + } + + void onCommand(CommandSender sender) + { + if (sender instanceof Player && sender.hasPermission("essentials.install")) + { + if (currentPlayer == null) + { + currentPlayer = (Player)sender; + if (updateCheck.isEssentialsInstalled()) + { + doManualUpdate(); + } + else + { + sender.sendMessage("Thank you for choosing Essentials."); + sender.sendMessage("The following installation wizard will guide you through the installation of Essentials."); + sender.sendMessage("Your answers will be saved for a later update."); + sender.sendMessage("Please answer the messages with yes or no, if not otherwise stated."); + sender.sendMessage("Write bye/exit/quit if you want to exit the wizard at anytime."); + + } + } + if (!currentPlayer.equals(sender)) + { + sender.sendMessage("The player " + currentPlayer.getDisplayName() + " is already using the wizard."); + } + } + else + { + sender.sendMessage("Please run the command as op from in game."); + } + } + + private void reactOnMessage(String message) + { + throw new UnsupportedOperationException("Not yet implemented"); + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/UpdatesDownloader.java b/EssentialsUpdate/src/com/earth2me/essentials/update/UpdatesDownloader.java new file mode 100644 index 000000000..28ffdfe3c --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/UpdatesDownloader.java @@ -0,0 +1,19 @@ +package com.earth2me.essentials.update; + +import java.io.File; + + +public class UpdatesDownloader +{ + + UpdatesDownloader() + { + + } + + void start(File updateFolderFile, VersionInfo newVersion) + { + + } + +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/Version.java b/EssentialsUpdate/src/com/earth2me/essentials/update/Version.java new file mode 100644 index 000000000..8e6cbc97f --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/Version.java @@ -0,0 +1,173 @@ +package com.earth2me.essentials.update; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class Version implements Comparable +{ + public enum Type + { + STABLE, PREVIEW, DEVELOPER + } + + public int getMajor() + { + return major; + } + + public int getMinor() + { + return minor; + } + + public int getBuild() + { + return build; + } + + public Type getType() + { + return type; + } + private final transient int major; + private final transient int minor; + private final transient int build; + private final transient Type type; + + public Version(final String versionString) + { + final Matcher matcher = Pattern.compile("(Pre|Dev)?([0-9]+)[_\\.]([0-9]+)[_\\.]([0-9]+).*").matcher(versionString); + if (!matcher.matches() || matcher.groupCount() < 4) + { + type = Type.DEVELOPER; + major = 99; + minor = build = 0; + return; + } + if (versionString.startsWith("Pre")) + { + type = Type.PREVIEW; + } + else if (versionString.startsWith("Dev")) + { + type = Type.DEVELOPER; + } + else + { + type = Type.STABLE; + } + major = Integer.parseInt(matcher.group(2)); + minor = Integer.parseInt(matcher.group(3)); + build = Integer.parseInt(matcher.group(4)); + } + + @Override + public int compareTo(final Version other) + { + int ret = 0; + if (other.getType() == Type.DEVELOPER && getType() != Type.DEVELOPER) + { + ret = -1; + } + else if (getType() == Type.DEVELOPER && other.getType() != Type.DEVELOPER) + { + ret = 1; + } + else if (other.getMajor() > getMajor()) + { + ret = -1; + } + else if (getMajor() > other.getMajor()) + { + ret = 1; + } + else if (other.getMinor() > getMinor()) + { + ret = -1; + } + else if (getMinor() > other.getMinor()) + { + ret = 1; + } + else if (other.getBuild() > getBuild()) + { + ret = -1; + } + else if (getBuild() > other.getBuild()) + { + ret = 1; + } + else if (other.getType() == Type.STABLE && getType() == Type.PREVIEW) + { + ret = -1; + } + else if (getType() == Type.STABLE && other.getType() == Type.PREVIEW) + { + ret = 1; + } + return ret; + } + + @Override + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final Version other = (Version)obj; + if (this.major != other.major) + { + return false; + } + if (this.minor != other.minor) + { + return false; + } + if (this.build != other.build) + { + return false; + } + if (this.type != other.type) + { + return false; + } + return true; + } + + @Override + public int hashCode() + { + int hash = 5; + hash = 71 * hash + this.major; + hash = 71 * hash + this.minor; + hash = 71 * hash + this.build; + hash = 71 * hash + (this.type != null ? this.type.hashCode() : 0); + return hash; + } + + @Override + public String toString() + { + final StringBuilder builder = new StringBuilder(); + if (type == Type.DEVELOPER) + { + builder.append("Dev"); + } + if (type == Type.PREVIEW) + { + builder.append("Pre"); + } + builder.append(major); + builder.append('.'); + builder.append(minor); + builder.append('.'); + builder.append(build); + return builder.toString(); + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/VersionInfo.java b/EssentialsUpdate/src/com/earth2me/essentials/update/VersionInfo.java new file mode 100644 index 000000000..9cd1e5edb --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/VersionInfo.java @@ -0,0 +1,48 @@ +package com.earth2me.essentials.update; + +import java.util.ArrayList; +import org.bukkit.configuration.Configuration; +import java.util.Collections; +import java.util.List; + + +public class VersionInfo +{ + private final transient List changelog; + private final transient int minBukkit; + private final transient int maxBukkit; + private final transient List modules; + + public VersionInfo(final Configuration updateConfig, final String path) + { + changelog = updateConfig.getList(path + ".changelog", Collections.emptyList()); + minBukkit = updateConfig.getInt(path + ".min-bukkit", 0); + maxBukkit = updateConfig.getInt(path + ".max-bukkit", 0); + modules = new ArrayList(); + final String modulesPath = path + ".modules"; + for (String module : updateConfig.getKeys(false)) + { + modules.add(new ModuleInfo(updateConfig, modulesPath + module)); + } + } + + public List getChangelog() + { + return Collections.unmodifiableList(changelog); + } + + public int getMinBukkit() + { + return minBukkit; + } + + public int getMaxBukkit() + { + return maxBukkit; + } + + public List getModules() + { + return Collections.unmodifiableList(modules); + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/Modules.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/Modules.java new file mode 100644 index 000000000..56d2445c9 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/Modules.java @@ -0,0 +1,7 @@ +package com.earth2me.essentials.update.states; + + +public class Modules +{ + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/ClientStateMonitor.java b/EssentialsUpdate/src/f00f/net/irc/martyr/ClientStateMonitor.java new file mode 100644 index 000000000..0b7303956 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/ClientStateMonitor.java @@ -0,0 +1,67 @@ +package f00f.net.irc.martyr; + +import java.util.Observable; +import java.util.Observer; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * ClientStateMonitor asks commands to update the client state. + */ +public class ClientStateMonitor implements Observer +{ + + static Logger log = Logger.getLogger(ClientStateMonitor.class.getName()); + + private IRCConnection connection; + + private boolean enabled = false; + + /** + * This should only be called by the IRCConnection itself. + * + * @param connection Connection we are associated with + */ + ClientStateMonitor( IRCConnection connection ) + { + this.connection = connection; + + enable(); + } + + public void enable() + { + if( enabled ) + return; + enabled = true; + + connection.addCommandObserver( this ); + } + + public void disable() + { + if( !enabled ) + return; + connection.removeCommandObserver( this ); + enabled = false; + } + + public void update( Observable observable, Object command_o ) + { + InCommand command = (InCommand)command_o; + + try + { + /*if( */command.updateClientState( connection.getClientState() );// ) + //log.debug("ClientStateMonnitor: Client state updated"); + } + catch( Throwable e ) + { + log.log(Level.SEVERE,"ClientStateMonitor: Client state update failed.", e); + } + + } + + // ===== END ClientStateMonitor +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/Command.java b/EssentialsUpdate/src/f00f/net/irc/martyr/Command.java new file mode 100644 index 000000000..ff8f168cd --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/Command.java @@ -0,0 +1,18 @@ +package f00f.net.irc.martyr; + +/** + * Defines an object which is a command, either incoming or outgoing. + */ +public interface Command +{ + /** + * Returns the string IRC uses to identify this command. Examples: + * NICK, PING, KILL, 332. Not strictly required for OutCommands + * as the irc identifier is expected to be part of the reder() + * result. + * + * @return The IRC identifier string + */ + String getIrcIdentifier(); +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandObserver.java b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandObserver.java new file mode 100644 index 000000000..5f988c0c3 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandObserver.java @@ -0,0 +1,5 @@ +package f00f.net.irc.martyr; + +public class CommandObserver extends StateObserver +{ +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandRegister.java b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandRegister.java new file mode 100644 index 000000000..2c7dca1dc --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandRegister.java @@ -0,0 +1,118 @@ +package f00f.net.irc.martyr; + +import java.util.Hashtable; + +import f00f.net.irc.martyr.commands.*; +import f00f.net.irc.martyr.errors.*; +import f00f.net.irc.martyr.replies.*; + +/** + * CommandRegister is basically a big hashtable that maps IRC + * identifiers to command objects that can be used as factories to + * do self-parsing. CommandRegister is also the central list of + * commands. + */ +public class CommandRegister +{ + + private Hashtable commands; + public CommandRegister() + { + commands = new Hashtable(); + + // Note that currently, we only have to register commands that + // can be received from the server. + new InviteCommand().selfRegister( this ); + new JoinCommand().selfRegister( this ); + new KickCommand().selfRegister( this ); + new MessageCommand().selfRegister( this ); + new ModeCommand().selfRegister( this ); + new IsonCommand().selfRegister( this ); + new NickCommand().selfRegister( this ); + new NoticeCommand().selfRegister( this ); + new PartCommand().selfRegister( this ); + new PingCommand().selfRegister( this ); + new QuitCommand().selfRegister( this ); + new TopicCommand().selfRegister( this ); + new WelcomeCommand().selfRegister( this ); + + // Register errors + new AlreadyRegisteredError().selfRegister( this ); + new CannotSendToChanError().selfRegister( this ); + new CantKillServerError().selfRegister( this ); + new ChannelBannedError().selfRegister( this ); + new ChannelInviteOnlyError().selfRegister( this ); + new ChannelLimitError().selfRegister( this ); + new ChannelWrongKeyError().selfRegister( this ); + new ChanOPrivsNeededError().selfRegister( this ); + new ErroneusNicknameError().selfRegister( this ); + new FileErrorError().selfRegister( this ); + new KeySetError().selfRegister( this ); + new LoadTooHighError().selfRegister( this ); + new NeedMoreParamsError().selfRegister( this ); + new NickCollisionError().selfRegister( this ); + new NickInUseError().selfRegister( this ); + new NoAdminInfoError().selfRegister( this ); + new NoLoginError().selfRegister( this ); + new NoMotdError().selfRegister( this ); + new NoNicknameGivenError().selfRegister( this ); + new NoOperHostError().selfRegister( this ); + new NoOriginError().selfRegister( this ); + new NoPermForHostError().selfRegister( this ); + new NoPrivilegesError().selfRegister( this ); + new NoRecipientError().selfRegister( this ); + new NoSuchChannelError().selfRegister( this ); + new NoSuchNickError().selfRegister( this ); + new NoSuchServerError().selfRegister( this ); + new NoTextToSendError().selfRegister( this ); + new NotOnChannelError().selfRegister( this ); + new NotRegisteredError().selfRegister( this ); + new PasswdMismatchError().selfRegister( this ); + new SummonDisabledError().selfRegister( this ); + new TooManyChannelsError().selfRegister( this ); + new TooManyTargetsError().selfRegister( this ); + new UModeUnknownFlagError().selfRegister( this ); + new UnknownCommandError().selfRegister( this ); + new UnknownModeError().selfRegister( this ); + new UserNotInChannelError().selfRegister( this ); + new UserOnChannelError().selfRegister( this ); + new UsersDisabledError().selfRegister( this ); + new UsersDontMatchError().selfRegister( this ); + new WasNoSuchNickError().selfRegister( this ); + new WildTopLevelError().selfRegister( this ); + new YoureBannedCreepError().selfRegister( this ); + + // Register replies + new ChannelCreationReply().selfRegister( this ); + new AwayReply().selfRegister( this ); + new ListEndReply().selfRegister( this ); + new ListReply().selfRegister( this ); + new ListStartReply().selfRegister( this ); + new LUserClientReply().selfRegister( this ); + new LUserMeReply().selfRegister( this ); + new LUserOpReply().selfRegister( this ); + new ModeReply().selfRegister( this ); + new NamesEndReply().selfRegister( this ); + new NamesReply().selfRegister( this ); + new NowAwayReply().selfRegister( this ); + new TopicInfoReply().selfRegister( this ); + new UnAwayReply().selfRegister( this ); + new WhoisChannelsReply().selfRegister( this ); + new WhoisEndReply().selfRegister( this ); + new WhoisIdleReply().selfRegister( this ); + new WhoisServerReply().selfRegister( this ); + new WhoisUserReply().selfRegister( this ); + } + + public void addCommand( String ident, InCommand command ) + { + commands.put( ident, command ); + } + + public InCommand getCommand( String ident ) + { + return commands.get( ident ); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandSender.java b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandSender.java new file mode 100644 index 000000000..a5a748e86 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandSender.java @@ -0,0 +1,14 @@ +package f00f.net.irc.martyr; + +/** + * A CommandSender can accept an OutCommand and do something with it + * (such as send it to the server, or send it on to another + * CommandSender). The idea is to create a chain of CommandSenders, + * with the last object in the chain the default CommandSender, + * created by IRCConnection. + * */ +public interface CommandSender +{ + CommandSender getNextCommandSender(); + void sendCommand( OutCommand command ); +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/CronManager.java b/EssentialsUpdate/src/f00f/net/irc/martyr/CronManager.java new file mode 100644 index 000000000..3c5d8b196 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/CronManager.java @@ -0,0 +1,80 @@ +package f00f.net.irc.martyr; + +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * @since 0.3.2 + * */ +public class CronManager +{ + private Timer timer; + + public CronManager() + { + timer = new Timer(); + } + + /** + * @param task TimerTask to schedule + * @param time When to schedule task + */ + public void schedule(TimerTask task, Date time) + { + timer.schedule(task, time); + } + + /** + * @param task TimerTask to schedule + * @param firstTime When to run first + * @param period How often to run + */ + public void schedule(TimerTask task, Date firstTime, long period) + { + timer.schedule(task, firstTime, period); + } + + /** + * @param task TimerTask to schedule + * @param delay How long to wait before running + */ + public void schedule(TimerTask task, long delay) + { + timer.schedule(task, delay); + } + + /** + * @param task TimerTask to schedule + * @param delay How long to wait before running + * @param period How often to run + */ + public void schedule(TimerTask task, long delay, long period) + { + timer.schedule(task, delay, period); + } + + /** + * @param task TimerTask to schedule + * @param firstTime When first to run + * @param period How often to run + */ + public void scheduleAtFixedRate( + TimerTask task, + Date firstTime, + long period) + { + timer.scheduleAtFixedRate(task, firstTime, period); + } + + /** + * @param task TimerTask to schedule + * @param delay When first to run + * @param period How often to run + */ + public void scheduleAtFixedRate(TimerTask task, long delay, long period) + { + timer.scheduleAtFixedRate(task, delay, period); + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/ForwardObservable.java b/EssentialsUpdate/src/f00f/net/irc/martyr/ForwardObservable.java new file mode 100644 index 000000000..7f4d8d89a --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/ForwardObservable.java @@ -0,0 +1,66 @@ +package f00f.net.irc.martyr; + +import java.util.Observer; +import java.util.Observable; +import java.util.LinkedList; +import java.util.List; + +/** + * Does notifications in the order they are added. + * */ +public class ForwardObservable extends Observable +{ + private boolean changed = true; + private List obs = new LinkedList(); + private final Object localMonitor = new Object(); + + + public void setChanged() + { + synchronized(localMonitor) + { + changed = true; + } + } + + protected void clearChanged() + { + synchronized(localMonitor) + { + changed = false; + } + } + + public void addObserver( Observer o ) + { + synchronized(localMonitor) + { + obs.add( o ); + } + } + + public void deleteObserver( Observer o ) + { + synchronized(localMonitor) + { + obs.remove( o ); + } + } + + public void notifyObservers(Object arg) + { + synchronized(localMonitor) + { + if (!changed) + return; + clearChanged(); + + for (Observer ob : obs) { + ob.update(this, arg); + } + } + } + + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/GenericAutoService.java b/EssentialsUpdate/src/f00f/net/irc/martyr/GenericAutoService.java new file mode 100644 index 000000000..0b3546231 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/GenericAutoService.java @@ -0,0 +1,54 @@ +package f00f.net.irc.martyr; + +import java.util.Observable; + +/** + * Provides a framework for an auto service. Does enable by default. + * Splits the 'update' method into two, 'updateState' and 'updateCommand'. + * Also provides thread safety on all methods. + */ +public abstract class GenericAutoService extends GenericCommandAutoService +{ + +protected GenericAutoService( IRCConnection connection ) +{ + super( connection ); +} + +public synchronized void enable() +{ + if( enabled ) + return; + + connection.addStateObserver( this ); + + super.enable(); +} + +public synchronized void disable() +{ + if( !enabled ) + return; + + connection.removeStateObserver( this ); + + super.disable(); +} + +public synchronized void update( Observable observer, Object updated ) +{ + if( !enabled ) + throw new IllegalStateException("This observer is not enabled." ); + if( updated instanceof State ) + updateState( (State)updated ); + else + super.update( observer, updated ); +} + +protected abstract void updateState( State state ); + +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/GenericCommandAutoService.java b/EssentialsUpdate/src/f00f/net/irc/martyr/GenericCommandAutoService.java new file mode 100644 index 000000000..b9c1d5ede --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/GenericCommandAutoService.java @@ -0,0 +1,79 @@ +package f00f.net.irc.martyr; + +import java.util.Observable; +import java.util.Observer; + +/** + * Provides a framework for an auto service that operates with + * InCommands. Does enable by default. Splits the 'update' method + * into two, 'updateState' and 'updateCommand'. Also provides thread + * safety on all methods. + */ +public abstract class GenericCommandAutoService implements Observer +{ + +protected boolean enabled = false; +protected IRCConnection connection; + +protected GenericCommandAutoService( IRCConnection connection ) +{ + this.connection = connection; + + enable(); +} + +public synchronized void enable() +{ + if( enabled ) + return; + + connection.addCommandObserver( this ); + enabled = true; +} + +public synchronized void disable() +{ + if( !enabled ) + return; + + connection.removeCommandObserver( this ); + enabled = false; +} + +public synchronized void update( Observable observer, Object updated ) +{ + if( !enabled ) + throw new IllegalStateException("This observer is not enabled." ); + if( updated instanceof State ) + { + throw new IllegalArgumentException("This is not a state observer." ); + } + else if( updated instanceof InCommand ) + { + updateCommand( (InCommand)updated ); + } + else + { + throw new IllegalArgumentException("Unknown object given to update."); + } +} + +protected IRCConnection getConnection() +{ + return connection; +} + +protected synchronized boolean isEnabled() +{ + return enabled; +} + +protected abstract void updateCommand( InCommand command ); + + +// END AutoRegister +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/IRCConnection.java b/EssentialsUpdate/src/f00f/net/irc/martyr/IRCConnection.java new file mode 100644 index 000000000..159f533cd --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/IRCConnection.java @@ -0,0 +1,1163 @@ +/* + * IRCConnection.java + * + * Copyright (C) 2000, 2001, 2002, 2003, 2004 Ben Damm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * See: http://www.fsf.org/copyleft/lesser.txt + */ + +package f00f.net.irc.martyr; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.InetAddress; +import java.net.Socket; +import java.util.LinkedList; +import java.util.Observer; +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.commands.UnknownCommand; +import f00f.net.irc.martyr.errors.UnknownError; +import f00f.net.irc.martyr.replies.UnknownReply; +import java.util.logging.Level; +import java.util.logging.Logger; + +// TODO: +// +// Add synchronous disconnect. +// +/** + *

IRCConnection is the core class for Martyr. + * IRCConnection manages the socket, giving commands to the server + * and passing results to the parse engine. It manages passing information out + * to the application via the command listeners and state listeners. + * IRCConnection has no IRC intelligence of its own, that is left + * up to the classes on the command and state listener lists. A number of + * listeners that do various tasks are provided as part of the framework.

+ * + *

Please read this entirely before using the framework. Or + * what the heck, try out the example below and see if it works for ya.

+ * + *

States and State Listeners

+ *

IRCConnection is always in one of three states. + * UNCONNECTED, UNREGISTERED or + * REGISTERED. It keeps a list of listeners that + * would like to know when a state change occurs. When a state change + * occurs each listener in the list, in the order they were added, is + * notified. If a listener early up on the list causes something to happen + * that changes the state before your listener gets notified, you will be + * notified of the state change even though the state has changed. You + * will be notified again of the new state. That is, state change + * notifications will always be in order, but they may not always reflect + * the "current" state.

+ * + *

Commands and Command Listeners

+ *

IRCConnection also keeps a list of listeners for + * when a command arrives from the server. When a command arrives, it + * is first parsed into an object. That object is then passed around + * to all the listeners, again, in order. Commands can be received + * and the socket closed before the commands are actually send to the + * listeners, so beware that even though you receive a command, you + * may not always be guaranteed to have an open socket to send a + * response back on. A consumer of the command should never modify + * the command object. If you try to send a command to a closed + * socket, IRCConnection will silently ignore your + * command. Commands should always be received in order by all + * listeners, even if a listener higher up in the list sends a + * response to the server which elicits a response back from the + * server before you've been told of the first command.

+ * + *

Connecting and staying connected

+ *

The AutoReconnect class can connect you and will try to stay + * connected. Using AutoReconnect to connect the + * first time is recommended, use the go(server,port) method once + * you are ready to start.

+ * + *

Registration On The Network

+ *

The AutoRegister class can register you automatically on the + * network. Otherwise, registration is left up to the consumer. + * Registration should occur any time the state changes to + * UNREGISTERED. The consumer will know this because it + * has registered some class as a state observer. + *

+ * + *

Auto Response

+ *

Some commands, such as Ping require an automatic response. + * Commands that fall into this category can be handled by the + * AutoResponder class. For a list of what commands + * AutoResponder auto responds to, see the source.

+ * + *

Joining and Staying Joined

+ *

You can use the AutoJoin class to join a channel + * and stay there. AutoJoin will try to re-join if + * kicked or if the connection is lost and the server re-connects. + * AutoJoin can be used any time a join is desired. If + * the server is not connected, it will wait until the server + * connects. If the server is connected, it will try to join right + * away.

+ * + *

Example Usage

+ *

You will probably want to at least use the + * AutoRegister and AutoResponder classes. + * Example:

+ * + *

Note that in the example, the first line is optional. + * IRCConnection can be called with its default + * constructor. See note below about why this is done. + * IRCConnection will instantiate its own + * ClientState object if you do not provide one.

+ * + *
+ * ClientState clientState = new MyAppClientState();
+ * IRCConnection connection = new IRCConnection( clientState );
+ *
+ * // AutoRegister and AutoResponder both add themselves to the
+ * // appropriate observerables.  Both will remove themselves with the
+ * // disable() method.
+ * 
+ * AutoRegister autoReg
+ *   = new AutoRegister( "repp", "bdamm", "Ben Damm", connection );
+ * AutoReconnect autoRecon = new AutoReconnect( connection );
+ * AutoResponder autoRes = new AutoResponder( connection );
+ *
+ * // Very important that the objects above get added before the connect.
+ * // If done otherwise, AutoRegister will throw an
+ * // IllegalStateException, as AutoRegister can't catch the
+ * // state switch to UNREGISTERED from UNCONNECTED.
+ *
+ * autoRecon.go( server, port );
+ * 
+ * + *

Client State

+ *

The ClientStateMonitor class tells commands to + * change the client state when they are received. + * ClientStateMonitor is automatically added to the + * command queue before any other command, so that you can be + * guaranteed that the ClientState is updated before any + * observer sees a command.

+ * + *

So, how does an application know when a channel has been joined, + * a user has joined a channel we are already on, etc? How does the + * application get fine-grained access to client state change info? + * This is a tricky question, and the current solution is to sublcass + * the clientstate.ClientState and + * clientstate.Channel classes with your own, overriding + * the setXxxxXxxx methods. Each method would call + * super.setXxxXxxx and then proceed to change the + * application as required.

+ * + *

Startup

+ *

IRCConnection starts in the UNCONNECTED state and + * makes no attempt to connect until the connect(...) + * method is called.

+ * + *

IRCConnection starts a single thread at + * construction time. This thread simply waits for events. An event + * is a disconnection request or an incoming message. Events are + * dealt with by this thread. If connect is called, a second thread + * is created to listen for input from the server (InputHandler). + * + * @see f00f.net.irc.martyr.A_FAQ + * @see f00f.net.irc.martyr.clientstate.ClientState + * @see f00f.net.irc.martyr.services.AutoRegister + * @see f00f.net.irc.martyr.services.AutoResponder + * @see f00f.net.irc.martyr.State + * + */ +/* + * Event handling re-org + * + * - A message is an event + * - A disconnect request is an event, placed on the queue? + * -- Off I go to do other stuff. + */ +public class IRCConnection { + static Logger log = Logger.getLogger(IRCConnection.class.getName()); + + public IRCConnection() + { + this( new ClientState() ); + } + + public IRCConnection( ClientState clientState ) + { + // State observers are notified of state changes. + // Command observers are sent a copy of each message that arrives. + stateObservers = new StateObserver(); + commandObservers = new CommandObserver(); + this.clientState = clientState; + stateQueue = new LinkedList(); + + commandRegister = new CommandRegister(); + commandSender = new DefaultCommandSender(); + + setState( State.UNCONNECTED ); + + new ClientStateMonitor( this ); + + localEventQueue = new LinkedList(); + + eventThread = new EventThread(); + eventThread.setDaemon( true ); + startEventThread(); + } + + /** + * This method exists so that subclasses may perform operations before + * the event thread starts, but overriding this method. + * */ + protected void startEventThread() + { + eventThread.start(); + } + + /** + * In the event you want to stop martyr, call this. This asks the + * event thread to finish the current event, then die. + * */ + public void stop() + { + eventThread.doStop(); + } + + /** + * Performs a standard connection to the server and port. If we are already + * connected, this just returns. + * + * @param server Server to connect to + * @param port Port to connect to + * @throws IOException if we could not connect + */ + public void connect( String server, int port ) + throws IOException + { + synchronized( connectMonitor ) + { + //log.debug("IRCConnection: Connecting to " + server + ":" + port); + if( connected ) + { + log.severe("IRCConnection: Connect requested, but we are already connected!"); + return; + } + + connectUnsafe( new Socket( server, port ), server ); + } + } + + /** + * This allows the developer to provide a pre-connected socket, ready for use. + * This is so that any options that the developer wants to set on the socket + * can be set. The server parameter is passed in, rather than using the + * customSocket.getInetAddr() because a DNS lookup may be undesirable. Thus, + * the canonical server name, whatever that is, should be provided. This is + * then passed on to the client state. + * + * @param customSocket Custom socket that we will connect over + * @param server Server to connect to + * @throws IOException if we could not connect + * @throws IllegalStateException if we are already connected. + */ + public void connect( Socket customSocket, String server ) + throws IOException, IllegalStateException + { + synchronized( connectMonitor ) + { + if( connected ) + { + throw new IllegalStateException( "Connect requested, but we are already connected!" ); + } + + connectUnsafe( customSocket, server ); + } + + } + + /** + *

Orders the socket to disconnect. This doesn't actually disconnect, it + * merely schedules an event to disconnect. This way, pending incoming + * messages may be processed before a disconnect actually occurs.

+ *

No errors are possible from the disconnect. If you try to disconnect an + * unconnected socket, your disconnect request will be silently ignored.

+ */ + public void disconnect() + { + synchronized( eventMonitor ) + { + disconnectPending = true; + eventMonitor.notifyAll(); + } + } + + /** + * Sets the daemon status on the threads that IRCConnection + * creates. Default is true, that is, new InputHandler threads are + * daemon threads, although the event thread is always a daemon. The + * result is that as long as there is an active connection, the + * program will keep running. + * + * @param daemon Set if we are to be treated like a daemon + */ + public void setDaemon( boolean daemon ) + { + this.daemon = daemon; + } + + /** + * Signal threads to stop, and wait for them to do so. + * @param timeout *2 msec to wait at most for stop. + * + * */ + public void shutdown(long timeout) + { + // Note: UNTESTED! + try + { + // 1) shut down the input thread. + synchronized( inputHandlerMonitor ) + { + if( inputHandler != null ) + { + inputHandler.signalShutdown(); + } + synchronized( socketMonitor ) + { + if( socket != null ) + { + try + { + socket.close(); + } + catch (IOException e) + { + // surprising? + } + } + } + if( inputHandler != null ) + { + inputHandler.join(timeout); + } + } + + // 2) shut down the event thread. + eventThread.shutdown(); + eventThread.join(timeout); + } + catch( InterruptedException ie ) + { + // We got interrupted - while waiting for death. + // Shame that. + } + } + + public String toString() + { + return "IRCConnection"; + } + + public void addStateObserver( Observer observer ) + { + //log.debug("IRCConnection: Added state observer " + observer); + stateObservers.addObserver( observer ); + } + + public void removeStateObserver( Observer observer ) + { + //log.debug("IRCConnection: Removed state observer " + observer); + stateObservers.deleteObserver( observer ); + } + + public void addCommandObserver( Observer observer ) + { + //log.debug("IRCConnection: Added command observer " + observer); + commandObservers.addObserver( observer ); + } + + public void removeCommandObserver( Observer observer ) + { + //log.debug("IRCConnection: Removed command observer " + observer); + commandObservers.deleteObserver( observer ); + } + + + public State getState() + { + return state; + } + + public ClientState getClientState() + { + return clientState; + } + + /** + * Accepts a command to be sent. Sends the command to the + * CommandSender. + * + * @param command Command we will send + * */ + public void sendCommand( OutCommand command ) + { + commandSender.sendCommand( command ); + } + + /** + * @return the first class in a chain of OutCommandProcessors. + * */ + public CommandSender getCommandSender() + { + return commandSender; + } + + /** + * @param sender sets the class that is responsible for sending commands. + * */ + public void setCommandSender( CommandSender sender ) + { + this.commandSender = sender; + } + + /** + * @return the local address to which the socket is bound. + * */ + public InetAddress getLocalAddress() + { + return socket.getLocalAddress(); + } + + public String getRemotehost() + { + return clientState.getServer(); + } + + /** + * Sets the time in milliseconds we wait after each command is sent. + * + * @param sleepTime Length of time to sleep between commands + * */ + public void setSendDelay( int sleepTime ) + { + this.sendDelay = sleepTime; + } + + /** + * @since 0.3.2 + * @return a class that can schedule timer tasks. + * */ + public CronManager getCronManager() + { + if( cronManager == null ) + cronManager = new CronManager(); + return cronManager; + } + + /** + * Inserts into the event queue a command that was not directly + * received from the server. + * + * @param fakeCommand Fake command to inject into incoming queue + * */ + public void injectCommand( String fakeCommand ) + { + synchronized( eventMonitor ) + { + localEventQueue.add( fakeCommand ); + eventMonitor.notifyAll(); + } + } + + // ===== package methods ============================================= + + void socketError( IOException ioe ) + { + //log.debug("Socket error called."); + //log.debug("IRCConnection: The stack of the exception:", ioe); + + //log.log(Level.SEVERE, "Socket error", ioe); + disconnect(); + } + + /** + * Splits a raw IRC command into three parts, the prefix, identifier, + * and parameters. + * @param wholeString String to be parsed + * @return a String array with 3 components, {prefix,ident,params}. + * */ + public static String[] parseRawString( String wholeString ) + { + String prefix = ""; + String identifier; + String params = ""; + + StringTokenizer tokens = new StringTokenizer( wholeString, " " ); + + if( wholeString.charAt(0) == ':' ) + { + prefix = tokens.nextToken(); + prefix = prefix.substring( 1, prefix.length() ); + } + + identifier = tokens.nextToken(); + + if( tokens.hasMoreTokens() ) + { + // The rest of the string + params = tokens.nextToken(""); + } + + String[] result = new String[3]; + result[0] = prefix; + result[1] = identifier; + result[2] = params; + + return result; + } + + /** + * Given the three parts of an IRC command, generates an object to + * represent that command. + * + * @param prefix Prefix of command object + * @param identifier ID of command + * @param params Params of command + * @return An InCommand object for the given command object + * */ + protected InCommand getCommandObject( String prefix, String identifier, String params ) + { + InCommand command; + + // Remember that commands are also factories. + InCommand commandFactory = commandRegister.getCommand( identifier ); + if( commandFactory == null ) + { + if( UnknownError.isError( identifier ) ) + { + command = new UnknownError( identifier ); + log.warning("IRCConnection: Using " + command); + } + else if( UnknownReply.isReply( identifier ) ) + { + command = new UnknownReply( identifier ); + //log.warning("IRCConnection: Using " + command); + } + else + { + // The identifier doesn't map to a command. + log.warning("IRCConnection: Unknown command"); + command = new UnknownCommand(); + } + } + else + { + command = commandFactory.parse( prefix, identifier, params); + + if( command == null ) + { + log.severe("IRCConnection: CommandFactory[" + commandFactory + "] returned NULL"); + return null; + } + //log.debug("IRCConnection: Using " + command); + } + + return command; + } + + + + /** + * Executed by the event thread. + * + * @param wholeString String to be parsed and handled + * */ + void incomingCommand( String wholeString ) + { + //log.info("IRCConnection: RCV = " + wholeString); + + // 1) Parse out the command + String cmdBits[]; + + try + { + cmdBits = parseRawString( wholeString ); + } + catch( Exception e ) + { + // So.. we can't process the command. + // So we call the error handler. + handleUnparsableCommand( wholeString, e ); + return; + } + + String prefix = cmdBits[0]; + String identifier = cmdBits[1]; + String params = cmdBits[2]; + + // 2) Fetch command from factory + InCommand command = getCommandObject( prefix, identifier, params ); + command.setSourceString( wholeString ); + + // Update the state and send out to commandObservers + localCommandUpdate( command ); + } + + protected void handleUnparsableCommand( String wholeString, Exception e ) + { + log.log(Level.SEVERE, "Unable to parse server message.", e ); + } + + /** + * Called only in the event thread. + * + * @param command Command to update + * */ + private void localCommandUpdate( InCommand command ) + { + // 3) Change the connection state if required + // This allows us to change from UNREGISTERED to REGISTERED and + // possibly back. + State cmdState = command.getState(); + if( cmdState != State.UNKNOWN && cmdState != getState() ) + setState( cmdState ); + + // TODO: Bug here? + + // 4) Notify command observers + try + { + commandObservers.setChanged(); + commandObservers.notifyObservers( command ); + } + catch( Throwable e ) + { + log.log(Level.SEVERE, "IRCConnection: Command notify failed.", e); + } + + } + + // ===== private variables =========================================== + + /** Object used to send commands. */ + private CommandSender commandSender; + + private CronManager cronManager; + + /** State of the session. */ + private State state; + + /** + * Client state (our name, nick, groups, etc). Stored here mainly + * because there isn't anywhere else to stick it. + */ + private ClientState clientState; + + /** + * Maintains a list of classes observing the state and notifies them + * when it changes. + */ + private StateObserver stateObservers; + + /** + * Maintains a list of classes observing commands when they come in. + */ + private CommandObserver commandObservers; + + /** + * The actual socket used for communication. + */ + private Socket socket; + + /** + * Monitor access to socket. + * */ + private final Object socketMonitor = new Object(); + + /** + * We want to prevent connecting and disconnecting at the same time. + */ + private final Object connectMonitor = new Object(); + + /** + * This object should be notified if we want the main thread to check for + * events. An event is either an incoming message or a disconnect request. + * Sending commands to the server is synchronized by the eventMonitor. + */ + private final Object eventMonitor = new Object(); + + /** + * This tells the processEvents() method to check if we should disconnect + * after processing all incoming messages. + */ + // Protected by: + // inputHandlerMonitor + // eventMonitor + // connectMonitor + private boolean disconnectPending = false; + + /** + * The writer to use for output. + */ + private BufferedWriter socketWriter; + + /** + * Command register, contains a list of commands that can be received + * by the server and have matching Command objects. + */ + private CommandRegister commandRegister; + + /** + * Maintains a handle on the input handler. + */ + private InputHandler inputHandler; + + /** + * Access control for the input handler. + */ + private final Object inputHandlerMonitor = new Object(); + + /** + * State queue keeps a queue of requests to switch state. + */ + private LinkedList stateQueue; + + /** + * localEventQueue allows events not received from the server to be + * processed. + * */ + private LinkedList localEventQueue; + + /** + * Setting state prevents setState from recursing in an uncontrolled + * manner. + */ + private boolean settingState = false; + + /** + * Event thread waits for events and executes them. + */ + private EventThread eventThread; + + /** + * Determines the time to sleep every time we send a message. We do this + * so that the server doesn't boot us for flooding. + */ + private int sendDelay = 300; + + /** + * connected just keeps track of whether we are connected or not. + */ + private boolean connected = false; + + /** + * Are we set to be a daemon thread? + */ + private boolean daemon = false; + + // ===== private methods ============================================= + + /** + * Unsafe, because this method can only be called by a method that has a lock + * on connectMonitor. + * + * @param socket Socket to connect over + * @param server Server to connect to + * @throws IOException if connection fails + */ + private void connectUnsafe( Socket socket, String server ) + throws IOException + { + synchronized(socketMonitor) + { + this.socket = socket; + } + + socketWriter = + new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) ); + + /** + * The reader to use for input. Managed by the InputHandler. + */ + BufferedReader socketReader = + new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); + + // A simple thread that waits for input from the server and passes + // it off to the IRCConnection class. + //if( inputHandler != null ) + //{ + // log.fatal("IRCConnection: Non-null input handler on connect!!"); + // return; + //} + + synchronized( inputHandlerMonitor ) + { + // Pending events get processed after a disconnect call, and there + // shouldn't be any events generated while disconnected, so it makes + // sense to test for this condition. + if( inputHandler != null && inputHandler.pendingMessages() ) + { + log.severe("IRCConnection: Tried to connect, but there are pending messages!"); + return; + } + + if( inputHandler != null && inputHandler.isAlive() ) + { + log.severe("IRCConnection: Tried to connect, but the input handler is still alive!"); + return; + } + + clientState.setServer( server ); + clientState.setPort( socket.getPort() ); + + connected = true; + + inputHandler = new InputHandler( socketReader, this, eventMonitor ); + inputHandler.setDaemon( daemon ); + inputHandler.start(); + } + setState( State.UNREGISTERED ); + } + + private class EventThread extends Thread + { + private boolean doShutdown = false; + + public EventThread() + { + super("EventThread"); + } + + public void run() + { + handleEvents(); + } + + public void shutdown() + { + synchronized(eventMonitor) + { + this.doShutdown = true; + eventMonitor.notifyAll(); + } + } + + private void handleEvents() + { + try + { + while( true ) + { + // Process all events in the event queue. + //log.debug("IRCConnection: Processing events"); + while( processEvents() ) { } + + // We can't process events while synchronized on the + // eventMonitor because we may end up in deadlock. + synchronized( eventMonitor ) + { + if( !doShutdown && !pendingEvents() ) + { + eventMonitor.wait(); + } + + if( doShutdown ) + { + return; + } + } + } + } + catch( InterruptedException ie ) + { + log.log(Level.WARNING, "Interrupted while handling events.", ie ); + // And we do what? + // We die, that's what we do. + } + } + + public void doStop() + { + shutdown(); + } + + public String toString() + { + return "EventThread"; + } + } + + /** + * This method synchronizes on the inputHandlerMonitor. Note that if + * additional event types are processed, they also need to be added to + * pendingEvents(). + * @return true if events were processed, false if there were no events to + * process. + */ + private boolean processEvents() + { + boolean events = false; + + // the inputHandlerMonitor here serves two purposes: To protect + // from inputHandler changes and to ensure only one thread is + // operating in processEvents. + // + // Perhaps a different monitor should be used? + synchronized( inputHandlerMonitor ) + { + while( inputHandler != null && inputHandler.pendingMessages() ) + { + String msg = inputHandler.getMessage(); + incomingCommand( msg ); + events = true; + } + + while( localEventQueue != null && !localEventQueue.isEmpty() ) + { + String msg = localEventQueue.removeFirst(); + incomingCommand( msg ); + events = true; + } + + if( disconnectPending ) + { + //log.debug("IRCConnection: Process events: Disconnect pending."); + doDisconnect(); + events = true; + } + } + + return events; + } + + /** + * Does no synchronization on its own. This does not synchronize on + * any of the IRCConnection monitors or objects and returns after making a + * minimum of method calls. + * @return true if there are pending events that need processing. + */ + private boolean pendingEvents() + { + if( inputHandler != null && inputHandler.pendingMessages() ) + return true; + if( disconnectPending ) + return true; + if( localEventQueue != null && !localEventQueue.isEmpty() ) + return true; + + return false; + } + + // Synchronized by inputHandlerMonitor, called only from processEvents. + private void doDisconnect() + { + synchronized( connectMonitor ) + { + disconnectPending = false; + + if( !connected ) + { + return; + } + connected = false; + + try + { + final long startTime = System.currentTimeMillis(); + final long sleepTime = 1000; + final long stopTime = startTime + sleepTime; + //log.debug("IRCConnection: Sleeping for a bit (" + // + sleepTime + ").."); + // Slow things down a bit so the server doesn't kill us + // Also, we want to give a second to let any pending messages + // get processed and any pending disconnect() calls to be made. + // It is important that we use wait instead of sleep! + while( stopTime - System.currentTimeMillis() > 0 ) + { + connectMonitor.wait( stopTime - System.currentTimeMillis() ); + } + } + catch( InterruptedException ie ) + { + // Ignore + } + + //log.debug("IRCConnection: Stopping input handler."); + // Deprecated? + // inputHandler.stop(); + // inputHandler = null; + + //log.debug("IRCConnection: Closing socket."); + try + { + socket.close(); + } + catch( IOException ioe ) + { + // And we are supposed to do what? + // This probably means we've called disconnect on a closed + // socket. + handleSocketCloseException( ioe ); + return; + } + finally + { + connected = false; + } + } + + // The input handler should die, because we closed the socket. + // We'll wait for it to die. + synchronized( inputHandlerMonitor ) + { + //log.debug("IRCConnection: Waiting for the input handler to die.."); + try + { + // log.debug("IRCConnection: Stack:"); + + if( inputHandler.isAlive() ) + inputHandler.join(); + else + { + //log.debug("IRCConnection: No waiting required, input hander is already dead."); + } + } + catch( InterruptedException ie ) + { + //log.debug("IRCConnection: Error in join(): " + ie); + } + //log.debug("IRCConnection: Done waiting for the input handler to die."); + } + + + // There may be pending messages that we should process before we + // actually notify all the state listeners. + processEvents(); + + // It is important that the state be switched last. One of the + // state listeners may try to re-connect us. + setState( State.UNCONNECTED ); + + } + + protected void handleSocketCloseException( IOException ioe ) + { + log.log(Level.WARNING, "Error closing socket.", ioe ); + } + + /** + * Signals to trigger a state change. Won't actually send a state change + * until a previous attempt at changing the state finishes. This is + * important if one of the state listeners affects the state (ie tries to + * reconnect if we disconnect, etc). + * + * @param newState New state to set connection to. + */ + private void setState( State newState ) + { + if( settingState ) + { + // We are already setting the state. We want to complete changing + // to one state before changing to another, so that we don't have + // out-of-order state change signals. + stateQueue.addLast( newState ); + return; + } + + settingState = true; + + if( state == newState ) + return; + + while( true ) + { + state = newState; + + //log.debug("IRCConnection: State switch: " + state); + + try + { + stateObservers.setChanged(); + stateObservers.notifyObservers( newState ); + } + catch( Throwable e ) + { + log.log(Level.SEVERE, "IRCConnection: State update failed.", e); + } + + if( stateQueue.isEmpty() ) + break; + newState = stateQueue.removeFirst(); + } + + settingState = false; + } + + private class DefaultCommandSender implements CommandSender + { + public CommandSender getNextCommandSender() + { + return null; + } + + public void sendCommand( OutCommand oc ) + { + finalSendCommand( oc.render() ); + } + } + + /** + * Sends the command down the socket, with the required 'CRLF' on the + * end. Waits for a little bit after sending the command so that we don't + * accidentally flood the server. + * + * @param str String to send + */ + private void finalSendCommand( String str ) + { + try + { + synchronized( eventMonitor ) + { + //log.info("IRCConnection: SEND= " + str); + + if( disconnectPending ) + { + //log.debug("IRCConnection: Send cancelled, disconnect pending."); + return; + } + + socketWriter.write( str + "\r\n" ); + socketWriter.flush(); + + try + { + // Slow things down a bit so the server doesn't kill us + // We do this after the send so that if the send fails the + // exception is handled right away. + Thread.sleep( sendDelay ); + } + catch( InterruptedException ie ) + { + // Ignore + } + } + } + catch( IOException ioe ) + { + socketError( ioe ); + } + } + // ----- END IRCConnection ------------------------------------------- +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/InCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/InCommand.java new file mode 100644 index 000000000..a1564d9ec --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/InCommand.java @@ -0,0 +1,99 @@ +package f00f.net.irc.martyr; + +import java.util.Iterator; + +import f00f.net.irc.martyr.clientstate.ClientState; + +/** + * Defines commands that come from the server. Errors and replies are + * incoming commands. + * + * @see f00f.net.irc.martyr.errors.GenericError + * @see f00f.net.irc.martyr.replies.GenericReply + */ +public interface InCommand extends Command +{ + + /** + * Some commands, when received by the server, can only occur in one + * state. Thus, when this command is received, the protocol should + * assume that it is in that state, and a state change may be + * triggered. A command can use the 'unknown' state to indicate it + * can be received in any state (for example, ping). + * + * @return State associated with command + */ + State getState(); + + /** + * Every incoming command should know how to register itself with the + * command register. + * + * @param commandRegister Command register we want to register with + */ + void selfRegister( CommandRegister commandRegister ); + + /** + * Parses a string and produces a formed command object, if it can. + * Should return null if it cannot form the command object. The + * identifier is usually ignored, except in the special case where + * commands can be identified by multiple identifiers. In that case, + * the behaviour of the command may change in sublte ways. + * + * @param prefix Prefix of the command + * @param identifier ID of the command + * @param params Parameters of the command + * @return InCommand instance for parsed command + */ + InCommand parse( String prefix, String identifier, String params ); + + /** + * Gives the command a copy of the raw string from the server. Called + * by IRCConnection after the command is parsed. + * + * @param str Sets the source string to be parsed + */ + void setSourceString( String str ); + + /** + * Allows a third party to receive a copy of the raw string. + * + * @return The original source string from the server + */ + String getSourceString(); + + /** + * Asks the command to ensure that information it knows about the + * state the server thinks the client is in matches what we have. + * Returns true if state changes were made. + * + * @param state Client state to be updated + * @return True or false if changes were made + */ + boolean updateClientState( ClientState state ); + + + /** + * Returns an iterator of String objects over the attribute names + * for this command. Warning: Still new, support for this is not + * yet widespread. Should return all possible attribute keys, not just + * those that have a value in the current context. + * + * @return Iterator of attribute keys + */ + Iterator getAttributeKeys(); + + /** + * Returns the attribute, or null if the attribute does not exist, + * or is not defined. + * + * @param key Attribute to get value of + * @return Attribute value or null if attribute doesn't exist + */ + String getAttribute( String key ); + +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/InputHandler.java b/EssentialsUpdate/src/f00f/net/irc/martyr/InputHandler.java new file mode 100644 index 000000000..a3830afa9 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/InputHandler.java @@ -0,0 +1,130 @@ +package f00f.net.irc.martyr; + +import java.util.LinkedList; +import java.io.BufferedReader; +import java.io.IOException; + +/** + * A simple class to help manage input from the stream. + */ +public class InputHandler extends Thread +{ + //static Logger log = Logger.getLogger(InputHandler.class); + + private BufferedReader reader; + private IRCConnection connection; + private final LinkedList messages; + + private final Object eventMonitor; + + private static int serialGen = 0; + private int serialNumber = serialGen++; + private boolean doShutdown = false; + + public InputHandler( BufferedReader reader, + IRCConnection connection, + Object eventMonitor ) + { + + super("InputHandler"); + this.reader = reader; + this.connection = connection; + messages = new LinkedList(); + this.eventMonitor = eventMonitor; + + //log.debug("IRCConnection: New"); + } + + /** + * Set the shutdown flag, so that after next read, or on any error, the thread will just exit. + */ + public void signalShutdown() + { + synchronized(this) + { + doShutdown = true; + } + } + + /** + * @return true if there are messages waiting to be processed. + */ + public boolean pendingMessages() + { + synchronized( messages ) + { + return ! messages.isEmpty(); + } + } + + /** + * Gets the message at the top of the message queue and removes it from the + * message queue. + * + * @return Message from top of list. + */ + public String getMessage() + { + synchronized( messages ) + { + return messages.removeFirst(); + } + } + + /** + * Waits for input from the server. When input arrives, it is added to a + * queue and eventMonitor.notifyAll() is called. + */ + public void run() + { + //log.debug("IRCConnection: Running"); + try{ + + String str; + while( true ) + { + synchronized(this) + { + if( doShutdown ) + { + return; + } + } + str = reader.readLine(); + if( str == null ) + { + connection.socketError( new IOException( "Socket disconnected" ) ); + return; + } + synchronized( messages ) + { + messages.addLast( str ); + } + synchronized( eventMonitor ) + { + eventMonitor.notifyAll(); + } + } + } + catch( IOException ioe ) + { + if( doShutdown ) + { + return; + } + connection.socketError( ioe ); + } + finally + { + //log.debug("IRCConnection: Input handler has DIED!"); + } + } + + public String toString() + { + return "InputHandler[" + serialNumber + "]"; + } + + // ----- END InputHandler -------------------------------------------- +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java new file mode 100644 index 000000000..5cc39e1a9 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java @@ -0,0 +1,103 @@ +package f00f.net.irc.martyr; + +/** + * Any class which is to represent a mode must implement this + * interface. They must also implement equals(...) so that if the + * parameter for either mode is null they are equal based on the + * character, and if both parameters are not null, base the equal + * on the character and the parameters being equal. + */ +public interface Mode +{ + /** + * A Mode can be constructed and asked to make copies of itself. + * + * @return New Mode instance + */ + Mode newInstance(); + + /** + * The character that represents this mode (ie o for operator) + * + * @return Character representation of mode + */ + char getChar(); + + /** + * Should return true if this mode requires a parameter. + * + * @return True or false if a param is required for mode + */ + boolean requiresParam(); + + /** + * This mode should be recorded in the list of channel modes. This + * would NOT include such things as operator status, as it is recored + * with the Member object. + * + * @return True or false of the mode should be recorded in the list of channels + */ + boolean recordInChannel(); + + /** + * Determines if there can be multiple versions of this mode in + * the channel. + * + * @return True or false if only one instance of mode can exist per channel + */ + boolean onePerChannel(); + + /** + * Returns the parameter that was set with setParam(...) + * + * @return Parameter that was set previously + */ + String getParam(); + + /** + * Sets the parameter that can be retrieved with getParam() + * + * @param str Parameter to set on mode + */ + void setParam( String str ); + + /** + * Sets the sign of the operation. Must be positive (granting), + * negative (revoking) or nosign (neutral operation). + * + * @param sign Sign (+/-) of the mode + */ + void setSign( Sign sign ); + + /** + * @return the sign of this mode. + */ + Sign getSign(); + + /** + * Finally, the Sign enumeration. + */ + public class Sign + { + public static final Sign POSITIVE = new Sign( "positive" ); + public static final Sign NEGATIVE = new Sign( "negative" ); + public static final Sign NOSIGN = new Sign( "nosign" ); + + private String name; + private Sign( String name ) + { + this.name = name; + } + + public String toString() + { + return name; + } + } + +} + + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/OutCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/OutCommand.java new file mode 100644 index 000000000..9e25c9ce9 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/OutCommand.java @@ -0,0 +1,24 @@ +package f00f.net.irc.martyr; + +/** + * Defines an outgoing command. Outgoing commands are very simple + * because all they need to do is be rendered. Outgoing commands do + * not change our state. + */ +public interface OutCommand extends Command +{ + + /** + * Forms a string appropriate to send to the server, if required. + * Some commands will have no such string, as they are received and not + * sent. The string returned is sent to the server verbatim. + * + * @return Rendered string + */ + String render(); + +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/State.java b/EssentialsUpdate/src/f00f/net/irc/martyr/State.java new file mode 100644 index 000000000..e1e60ce9d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/State.java @@ -0,0 +1,31 @@ +package f00f.net.irc.martyr; + +/** + * A simple container for state constants. The state constants here + * are used to specify what state the protocol is in. The State + * object is both the state representitive and the state container. + * This was done so that state could be typesafe and valuesafe. + * + */ +public class State +{ + + public static final State UNCONNECTED = new State("unconnected"); + public static final State UNREGISTERED = new State("unregistered"); + public static final State REGISTERED = new State("registered"); + public static final State UNKNOWN = new State("unknown/any"); + + private String stateName; + + private State( String str ) + { + stateName = str; + } + + public String toString() + { + return stateName; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/StateObserver.java b/EssentialsUpdate/src/f00f/net/irc/martyr/StateObserver.java new file mode 100644 index 000000000..4b7a6693c --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/StateObserver.java @@ -0,0 +1,8 @@ +package f00f.net.irc.martyr; + +/** + * Should the state and state observer be one? + */ +public class StateObserver extends ForwardObservable +{ +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/TimerTaskCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/TimerTaskCommand.java new file mode 100644 index 000000000..00ab56f56 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/TimerTaskCommand.java @@ -0,0 +1,57 @@ +package f00f.net.irc.martyr; + +import java.util.TimerTask; + +// TODO: BD: Unit test +// TODO: BD: synchronization semantics? + +/** + * This class delays sending a command to the IRC connection. + * + * @author Morgan Christiansson + */ +public class TimerTaskCommand extends TimerTask +{ + + private IRCConnection _conn; + private OutCommand _cmd; + public TimerTaskCommand(IRCConnection conn, OutCommand cmd) + { + _conn = conn; + _cmd = cmd; + } + /* (non-Javadoc) + * @see java.util.TimerTask#run() + */ + public synchronized void run() + { + if( !isScheduled ) + return; + + _conn.sendCommand(_cmd); + isScheduled = false; + } + + private boolean isScheduled = true; + + /* (non-Javadoc) + * @see java.util.TimerTask#cancel() + */ + public synchronized boolean cancel() + { + boolean ret = super.cancel(); + isScheduled = false; + return ret; + } + + /** + * @return true if the command has yet to run or is running, false + * otherwise. + */ + public synchronized boolean isScheduled() + { + return isScheduled; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java new file mode 100644 index 000000000..d1d39c31d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java @@ -0,0 +1,373 @@ +package f00f.net.irc.martyr.clientstate; + +import java.util.Date; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; + +import f00f.net.irc.martyr.Command; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.Mode; +import f00f.net.irc.martyr.modes.channel.OperMode; +import f00f.net.irc.martyr.modes.channel.VoiceMode; +import f00f.net.irc.martyr.util.FullNick; +//import org.apache.log4j.Logger; + +/** + * Channel is simply a repository for information about a channel. + * Contains channel name, topic, who created the topic, when the topic + * was created, who is in the channel, mode, etc. + * + *

If a user of the framework wishes to use their own Member object + * (to trap events like setting/removing ops), then subclass + * Channel and add a method as follows.

+ * + *
+ * public Member makeMember( String member )
+ * {
+ *     return MyMemberSubClass( member ) );
+ * }
+ * 
+ * + *

Each of the methods in Channel that need to create a Member + * object (many are just temporary members, for the enhanced 'equals') + * calls makeMember instead of new Member(...). That is why this + * version of addMember is protected, so that a part of the framework + * won't do something silly like:

+ * + *
+ *      ...
+ *      channel.addMember( new Member( member ) );
+ *      ...
+ * 
+ */ +public class Channel +{ + + //static Logger log = Logger.getLogger(Channel.class); + + private String name = null; + private String topic = null; + private String topicAuthor = null; + private Date topicDate = null; + private Date creationDate = null; + + private List modes = null; + + /** + * Hopefully we can replace this with a more useful data structure. + * This is a vector of Member objects. + */ + private Vector members; + + public Channel( String chanName ) + { + this.name = chanName; + members = new Vector(); + modes = new LinkedList(); + } + + public String getName() + { + return name; + } + + protected void addMember( Member member ) + { + members.addElement( member ); + } + + /** + * Adds the member to the channel. + * + * @param member Member to add to the channel + * @param why Command that caused the member to be added + * @deprecated Use addMember( String, InCommand ) + * instead. + */ + public void addMember( String member, Command why ) + { + addMember( makeMember( member ) ); + } + + /** + * Adds the member to the channel. + * + * @param member Nick to add to the channel + * @param why Command that caused the member to be added + */ + public void addMember( String member, InCommand why ) + { + addMember( makeMember( member ) ); + } + + + /** + * @param nick Nick to add to the channel + * @param why Command that caused the member to be added + * @deprecated Use addMember( FullNick, InCommand ) intead. + */ + public void addMember( FullNick nick, Command why ) + { + addMember( makeMember( nick.getNick() )); + } + + /** + * @param nick Nick to add to the channel + * @param why Command that caused the member to be added + * Adds the member to the channel. Just calls nick.getNick(). + */ + public void addMember( FullNick nick, InCommand why ) + { + addMember( nick.getNick(), why ); + } + + /** + * Removes the user from the channel. Ignores leading @ or + symbols. + * This is the cononical version of removeMember. + * @param member Nick of the person leaving. + * @param why Command issed that caused this action. + */ + public void removeMember( String member, InCommand why ) + { + removeMember( makeMember( member ) ); + } + + /** + * @param member Nick to remove from channel + * @param why Command that caused removal + * @deprecated Use removeMember( String, InCommand ) instead. + * */ + public void removeMember( String member, Command why ) + { + removeMember( makeMember( member ) ); + } + + /** + * @param member Member to remove from channel + * @param why Command that caused removal + * @deprecated Use removeMember( FullNick, InCommand ) instead. + * */ + public void removeMember( FullNick member, Command why ) + { + removeMember( member, (InCommand)why ); + } + + /** + * Simply a wrapper to allow FullNicks to be used. Calls the string + * version of removeMember with nick.getNick(). + * + * @param nick Nick to remove from channel + * @param why Command that caused removal + */ + public void removeMember( FullNick nick, InCommand why ) + { + removeMember( nick.getNick(), why ); + } + + protected void removeMember( Member compareTo ) + { + for( int i = 0; i < members.size(); ++i ) + { + if( (members.elementAt( i )).equals( compareTo ) ) + { + members.removeElementAt( i ); + return; + } + } + } + + /** + * Informs the channel of a mode change. A mode change might be for the + * channel (such as l, n, or t) or for a user on this channel (such as + * o). + * + * @param mode Mode to set on the channel + */ + public void setMode( Mode mode ) + { + // Note that Modes are supposed to be equal if the character is + // equal. Thus, we can remove a mode from the set, even though it + // is different because its sign or parameters may be different. + if( mode.onePerChannel() && modes.contains( mode ) ) + { + modes.remove( mode ); + } + + if( (mode.getSign() != Mode.Sign.NEGATIVE) && mode.recordInChannel() ) + { + modes.add( mode ); + } + + if( mode instanceof OperMode ) + { + OperMode oMode = (OperMode)mode; + Member member = findMember( oMode.getParam() ); + + member.setOps( oMode.getSign() == Mode.Sign.POSITIVE ); + } + else if( mode instanceof VoiceMode ) + { + VoiceMode vMode = (VoiceMode)mode; + Member member = findMember( vMode.getParam() ); + + member.setVoice( vMode.getSign() == Mode.Sign.POSITIVE ); + } + } + + public Iterator getModes() + { + return modes.iterator(); + } + + /** + * Returns an enumeration of Member objects, in no particular order. + * + * @return List of members in the channel + */ + public Enumeration getMembers() + { + return members.elements(); + } + + /** + * Determines if the nick is in the channel. Nick can be in the form + * "@sork" or "+sork" or just "sork", for example. + * + * @param nick Nick of member to check + * @return True or false if the member is in this channel. + */ + public boolean isMemberInChannel( String nick ) + { + return isMemberInChannel( makeMember( nick ) ); + } + + /** + * Determines if the member is in this channel. + * + * @param member Member to check + * @return True or false if the member is in this channel. + */ + protected boolean isMemberInChannel( Member member ) + { + return findMember( member ) != null; + } + + /** + * Finds the Member object associated with a specific nick. Ignores + * prefixed + or @. + * + * @param nick Nick to check whether it's a member of the channel or not + * @return Member object for specified nick, if it exists (null if not) + */ + public Member findMember( String nick ) + { + return findMember( makeMember( nick ) ); + } + + protected Member findMember( Member member ) + { + Enumeration membersE = getMembers(); + while( membersE.hasMoreElements() ) + { + Member memberCompare = (Member)membersE.nextElement(); + + if( memberCompare.equals( member ) ) + { + return memberCompare; + } + } + + return null; + } + + public void setTopic( String topic ) + { + //log.debug(getName()+": Topic: " + topic); + this.topic = topic; + } + + public String getTopic() + { + return topic; + } + + public Date getTopicDate() + { + return topicDate; + } + + public void setTopicDate( Date date ) + { + //log.debug(getName()+": Topic date: " + date); + this.topicDate = date; + } + + public Date getCreationDate() + { + return creationDate; + } + + public void setCreationDate( Date date ) + { + //log.debug(getName()+": Creation date: " + date); + this.creationDate = date; + } + + public String getTopicAuthor() + { + return topicAuthor; + } + + public void setTopicAuthor( String author ) + { + //log.debug(getName()+": Topic by: " + author); + this.topicAuthor = author; + } + + /** + * To use a customized Member class, override this. + * + * @param nick Nickname to create a member object for + * @return Member object for nick + */ + protected Member makeMember( String nick ) + { + return new Member( nick ); + } + + + /** + * Determines if the string represents a channel name or not. + * + * @param str String to test if it's a channel or not + * @return True or false if a string looks like a channel + */ + public static boolean isChannel( String str ) + { + return str.charAt(0) == '#' || str.charAt(0) == '!' || str.charAt(0) == '&'; + } + + /** + * Compares the two channel names for equality. Returns false if + * either are null. + * + * @param one Left side of comparison + * @param two Right side of comparison + * @return True or false whether two channels are equal, false of either are null/ + */ + public static boolean areEqual( String one, String two ) + { + if( one == null || two == null ) + { + return false; + } + + return one.equalsIgnoreCase( two ); + } +} + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java new file mode 100644 index 000000000..c508463d9 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java @@ -0,0 +1,193 @@ +/* + * Original version: Ben Damm + * Changes by: mog + * - Added isOnChannel + * + */ +package f00f.net.irc.martyr.clientstate; + +import java.util.Enumeration; +import java.util.Hashtable; + +import f00f.net.irc.martyr.util.FullNick; +//import org.apache.log4j.Logger; + +/** + *

Maintains a list of client-related facts such as what channels we + * are in, who else is in the channels, what our nick is, etc.

+ * + *

ClientState is a critical part of martyr. To get access to events + * that change the client state, the framework user can subclass + * ClientState and then pass the subclass to the IRCConnection's + * constructor. Then, when a command detects a change in client + * state, it will call the corresponding method in the custom + * ClientState.

+ * + *

If a user of the framework wishes to grab client state information + * about a channel (when a user joins, when a user leaves, topic + * change, etc), the user can do so in a similar manner. Simply + * override the 'addChannel(String)' method to instantiate their own + * Channel subclass, and call the protected 'addChannel' method. See + * the addChannel method for an example. + *

+ * + */ +public class ClientState +{ + + //static Logger log = Logger.getLogger(ClientState.class); + + private FullNick nick = null; + private String user = ""; + private String name = ""; + private String pass = null; + private String server = ""; + private int port = -1; + + // Hashtable is threadsafe so we don't have to be. + protected Hashtable channels = new Hashtable(); + + public void setNick( FullNick nick ) + { + if( nick == null ) + { + //log.debug("ClientState: Set nick to null"); + } + else + { + //log.debug("ClientState: Set nick to \"" + nick + "\""); + } + this.nick = nick; + } + + public FullNick getNick() + { + return nick; + } + + public void setUser( String user ) + { + this.user = user; + } + + /** + * @return the username that was used to register. + * */ + public String getUser() + { + return user; + } + + public void setName( String name ) + { + this.name = name; + } + + /** + * @return the name (any arbitrary string) that was used to register. + * */ + public String getName() + { + return name; + } + + /** + * @return the password that was used to register. + */ + public String getPass() + { + return pass; + } + + public void setPass(String pass) + { + this.pass = pass; + } + + public void setServer( String server ) + { + this.server = server; + } + + public String getServer() + { + return server; + } + + public void setPort( int port ) + { + this.port = port; + } + + public int getPort() + { + return port; + } + + /** + *

Adds a channel to the list of channels we know about. If you + * want to supply your own Channel object, override this method + * with:

+ *
+     * public void addChannel( String channame )
+     * {
+     *     addChannel( new MyChannel( channame ) );
+     * }
+     * 
+ * + * @param channame Channel to add to list of channels + */ + public void addChannel( String channame ) + { + addChannel( new Channel( channame ) ); + } + + protected void addChannel( Channel channel ) + { + //log.debug("ClientState: Channel added: " + channel.getName()); + channels.put( channel.getName().toLowerCase(), channel ); + } + + public Channel getChannel( String chanName ) + { + return channels.get( chanName.toLowerCase() ); + } + + /** + * Removes a channel from the state, does nothing if the channel name + * is invalid. + * Should we throw an exception here? + * + * @param channel Channel to remove from list + */ + public void removeChannel( String channel ) + { + //log.debug("ClientState: Channel removed: " + channel); + channels.remove( channel.toLowerCase() ); + } + + public boolean isOnChannel( String channel ) + { + for (Enumeration iter = getChannelNames(); iter.hasMoreElements();) + { + if(channel.equalsIgnoreCase((String) iter.nextElement())) + { + return true; + } + } + return false; + } + + public Enumeration getChannelNames() + { + return channels.keys(); + } + + public Enumeration getChannels() + { + return channels.elements(); + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java new file mode 100644 index 000000000..489f21961 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java @@ -0,0 +1,114 @@ +package f00f.net.irc.martyr.clientstate; + +import f00f.net.irc.martyr.util.FullNick; + +/** + *

This class allows channels to keep track of individual users. Each + * user in the channel has a nick and has voice, ops, both, or none. + * Note that nicks can change, but the information we have about that + * person does not.

+ * + *

Control over events that happen to this class can be obtained in + * a similar fashion to how control for the Channel is taken from + * ClientState.

+ */ +public class Member +{ + + private FullNick nick; + private boolean hasOpsV = false; + private boolean hasVoiceV = false; + + /** + *

Strips off the leading 'at' or 'plus', sets ops or voice, and + * keeps the nick. Calls the methods setVoice(...) and + * setOps(...) from the constructor, if those conditions + * are true. The nick is set before setVoice or setOps are + * called.

+ * + * @param nickStr Nick of member + */ + public Member( String nickStr ) + { + char first = nickStr.charAt(0); + String shortNick = nickStr.substring(1, nickStr.length() ); + if( first == '@' ) + { + nick = new FullNick( shortNick ); + setOps( true ); + } + else if( first == '+' ) + { + nick = new FullNick( shortNick ); + setVoice( true ); + } + else + { + nick = new FullNick( nickStr ); + } + } + + /** + * Does a nick-wise compare. + * + * @param member Member to compare against + * @return True or false of this member equals the other one + */ + public boolean equals( Member member ) + { + return equals( member.nick ); + } + + public boolean equals( FullNick fullNick ) + { + return nick.equals( fullNick ); + } + + public boolean equals( Object o ) + { + if( o instanceof Member ) + return equals( (Member)o ); + else if( o instanceof FullNick ) + return equals( (FullNick)o ); + else return false; + } + + public int hashCode() + { + return nick.hashCode(); + } + + public void setOps( boolean ops ) + { + hasOpsV = ops; + } + + public void setVoice( boolean voice ) + { + hasVoiceV = voice; + } + + public boolean hasOps() + { + return hasOpsV; + } + + public boolean hasVoice() + { + return hasVoiceV; + } + + public void setNick( FullNick nick ) + { + this.nick = nick; + } + + public FullNick getNick() + { + return nick; + } + +} + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractCommand.java new file mode 100644 index 000000000..a3e3ef2c2 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractCommand.java @@ -0,0 +1,32 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.OutCommand; + +/** + * Defines a generic command. Most commands will simply have to + * override the getIrcIdentifier method and implement the parse and + * render methods using convenience methods. + */ +public abstract class AbstractCommand extends AbstractInCommand implements OutCommand +{ + + /** + * Forms a string appropriate to send to the server. All commands can + * be sent by the client. + */ + public String render() + { + // no prefix, since we are sending as a client. + return getIrcIdentifier() + " " + renderParams(); + } + + /** + * Renders the parameters of this command. + * + * @return String of rendered parameters + */ + public abstract String renderParams(); + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java new file mode 100644 index 000000000..97f305241 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java @@ -0,0 +1,174 @@ +package f00f.net.irc.martyr.commands; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.CommandRegister; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.clientstate.ClientState; + +/** + * Defines a generic command. Most commands will simply have to + * override the getIrcIdentifier method and implement the parse and + * render methods using convenience methods. + */ +public abstract class AbstractInCommand implements InCommand +{ + + protected Map attributes = new HashMap(); + + protected AbstractInCommand() + { + } + + protected AbstractInCommand( String[] attributeNames ) + { + for (String attributeName : attributeNames) { + attributes.put(attributeName, null); + } + } + + public String getAttribute( String key ) + { + return attributes.get( key ); + } + + public Iterator getAttributeKeys() + { + return Collections.unmodifiableSet( attributes.keySet() ).iterator(); + } + + protected void setAttribute( String key, String value ) + { + attributes.put( key, value ); + } + + private String sourceString; + + /** + * Some commands, when received by the server, can only occur in one + * state. Thus, when this command is received, the protocol should + * assume that it is that state. A command can use the 'unknown' + * state to indicate it can be received in any state (for example, + * ping). Most commands will occur in the REGISTERED state, so for a + * few exeptions, commands can leave this alone. + */ + public State getState() + { + return State.REGISTERED; + } + + /** + * Every command should know how to register itself (or not) with the + * command parsing engine. If a command is available under mutiple + * identifiers, then this method can be overridden and the addCommand + * method can be called multiple times. + */ + public void selfRegister( CommandRegister commandRegister ) + { + commandRegister.addCommand( getIrcIdentifier(), this ); + } + + /** + * Parses a string and produces a formed command object, if it can. + * Should return null if it cannot form the command object. + */ + public abstract InCommand parse( String prefix, String identifier, String params ); + + /** + * By default, commands do not update the client state. + */ + public boolean updateClientState( ClientState state ) + { + return false; + } + + /** + * Utility method to make parsing easy. Provides parameter n, where + * n=0 is the first parameter. Parses out the : and considers + * anything after a : to be one string, the final parameter. + * + * If the index doesn't exist, returns null. Should it throw + * IndexOutOfBoundsException? No, some commands may have optional + * fields. + * + * @param params String with parameters in it + * @param num Position number of parameter to be requested + * @return Parameter specified by id in params string + */ + public String getParameter( String params, int num ) + { + int colonIndex = params.indexOf( " :" ); + colonIndex++; // Skip the space, we just needed it to be sure it's really a "rest of line" colon + String textParam = null; + String spaceParams; + + if( colonIndex < 0 ) + { + spaceParams = params; + } + else if( colonIndex == 0 ) + { + if( num == 0 ) + return params.substring( 1, params.length() ); + else + return null; + // throw exception? + } + else + { + // colon index > 0, so we have at least one parameter before + // the final parameter. + spaceParams = params.substring( 0, colonIndex ).trim(); + textParam = params.substring( colonIndex + 1, params.length() ); + } + + StringTokenizer tokens = new StringTokenizer( spaceParams, " " ); + + while( tokens.hasMoreTokens() && num > 0 ) + { + // strip off tokensi + --num; + tokens.nextToken(); + } + + if( num == 0 && tokens.hasMoreTokens() ) + return tokens.nextToken(); + if( num == 0 && !tokens.hasMoreTokens() ) + return textParam; + + + return null; + // throw exception? + } + + public int getIntParameter( String params, int paramnum, int defaultNum ) + { + try + { + return Integer.parseInt( getParameter( params, paramnum ) ); + } + catch( NumberFormatException nfe ) + { + return defaultNum; + } + + } + + public void setSourceString( String source ) + { + this.sourceString = source; + } + + public String getSourceString() + { + return sourceString; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ActionCtcp.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ActionCtcp.java new file mode 100644 index 000000000..f599f16b7 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ActionCtcp.java @@ -0,0 +1,12 @@ +package f00f.net.irc.martyr.commands; + +/** + * ActionCtcp allows the application to do a '/me'. + */ +public class ActionCtcp extends CtcpMessage +{ + public ActionCtcp( String dest, String message ) + { + super( dest, "ACTION " + message ); + } +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ChannelModeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ChannelModeCommand.java new file mode 100644 index 000000000..f8305852b --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ChannelModeCommand.java @@ -0,0 +1,189 @@ +package f00f.net.irc.martyr.commands; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.Mode; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.modes.channel.AnonChannelMode; +import f00f.net.irc.martyr.modes.channel.BanMode; +import f00f.net.irc.martyr.modes.channel.ExceptionMode; +import f00f.net.irc.martyr.modes.channel.InviteMaskMode; +import f00f.net.irc.martyr.modes.channel.InviteOnlyMode; +import f00f.net.irc.martyr.modes.channel.KeyMode; +import f00f.net.irc.martyr.modes.channel.LimitMode; +import f00f.net.irc.martyr.modes.channel.ModeratedMode; +import f00f.net.irc.martyr.modes.channel.NoExtMsgMode; +import f00f.net.irc.martyr.modes.channel.OperMode; +import f00f.net.irc.martyr.modes.channel.PrivateMode; +import f00f.net.irc.martyr.modes.channel.SecretMode; +import f00f.net.irc.martyr.modes.channel.TopicLockMode; +import f00f.net.irc.martyr.modes.channel.VoiceMode; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Defines the ChannelMode command. Can be used to send a Channel + * mode. For receiving, this defines which channel modes Martyr knows + * about and passes them on to the Channel object. Note that the + * actual logic of what happens when a mode arrives lies in the + * clientstate.Channel object. + */ +public class ChannelModeCommand extends ModeCommand +{ + + private String prefix; + private String channelName; + private FullNick sender; + + private List modes; + + private static HashMap modeTypes; + + /** + * For receiving a mode command. + * @param prefix Currently unused prefix string + * @param channelName Channel that the mode change is in reference to + * @param params List of params to be parsed + */ + public ChannelModeCommand( String prefix, String channelName, + StringTokenizer params ) + { + makeModes(); + + this.prefix = prefix; + this.channelName = channelName; + + modes = parseModes( modeTypes, params ); + + // System.out.println( modes ); + } + + /** + * For sending a mode discovery. + * + * @param channelName Channel that the mode change is in reference to + */ + public ChannelModeCommand( String channelName ) + { + sender = null; + this.channelName = channelName; + + // Empty list, no modes. + modes = new LinkedList(); + } + + public void makeModes() + { + if( modeTypes == null ) + { + modeTypes = new HashMap(); + + registerMode( modeTypes, new BanMode() ); + registerMode( modeTypes, new KeyMode() ); + registerMode( modeTypes, new OperMode() ); + registerMode( modeTypes, new VoiceMode() ); + registerMode( modeTypes, new LimitMode() ); + // registerMode( modeTypes, new QuietMode() ); + registerMode( modeTypes, new SecretMode() ); + registerMode( modeTypes, new PrivateMode() ); + registerMode( modeTypes, new NoExtMsgMode() ); + registerMode( modeTypes, new ExceptionMode() ); + registerMode( modeTypes, new TopicLockMode() ); + registerMode( modeTypes, new ModeratedMode() ); + registerMode( modeTypes, new InviteMaskMode() ); + registerMode( modeTypes, new InviteOnlyMode() ); + registerMode( modeTypes, new AnonChannelMode() ); + } + } + + /** + * Shouldn't be called, as ModeCommand should be responsible for parsing + * and creating this class. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + throw new IllegalStateException( "Don't call this method!" ); + } + + public String render() + { + return "MODE " + channelName + renderParams(); + } + + public String renderParams() + { + Iterator modesI = modes.iterator(); + + String modes = ""; + String params = ""; + + while( modesI.hasNext() ) + { + Mode mode = (Mode)modesI.next(); + + if( mode.getSign() != Mode.Sign.NOSIGN ) + { + modes += (mode.getSign() == Mode.Sign.POSITIVE ? "+" : "-" ); + } + modes += mode.getChar(); + + if( mode.getParam() != null ) + { + // Does the parameter list already have params? + // If so, stick in a space. + if( params.length() > 0 ) + { + params += " "; + } + params += mode.getParam(); + } + } + + return modes + " " + params; + } + + public String getChannel() + { + return channelName; + } + + public FullNick getSender() + { + return sender; + } + + public String getPrefix() { + return prefix; + } + + /** + * Passes the modes on to the clientstate.Channel object. + */ + public boolean updateClientState( ClientState state ) + { + boolean changed = false; + + Iterator modesI = modes.iterator(); + Channel channel = state.getChannel( channelName ); + + while( modesI.hasNext() ) + { + Mode mode = (Mode)modesI.next(); + + channel.setMode( mode ); + + changed = true; + } + + return changed; + } + + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpMessage.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpMessage.java new file mode 100644 index 000000000..6012aa0ab --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpMessage.java @@ -0,0 +1,129 @@ +package f00f.net.irc.martyr.commands; + +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.util.FullNick; + +/** + * This facilitates the sending and receiving of CTCP messages. Upon + * receiving a message, MessageCommand checks to see if it is a CTCP, + * and if it is, it instantiates this class instead of a + * MessageCommand. You can then use the getAction() and getMessage() + * methods to retreive the action and payload, respectively. + * + * @see MessageCommand + */ +public class CtcpMessage extends MessageCommand +{ + private String actionStr; + + /** + * Use this to send a CTCP message. This simply wraps the string + * with the CTCP tags, \001. + * + * @param dest Target of CTCP message + * @param message Actual CTCP message + */ + public CtcpMessage( String dest, String message ) + { + super( dest, "\001" + message + "\001" ); + } + + public CtcpMessage( String dest, String action, String message ) + { + this( dest, action + " " + message ); + } + + /** + * This is only to be called by MessageCommand, as a way of + * receiving a Ctcp message. It strips the \001's off and holds + * the message left over. + * + * @param from Nick that sent the message + * @param dest Target of the CTCP message + * @param message Actual CTCP message + */ + protected CtcpMessage( FullNick from, String dest, String message ) + { + super( from, dest, getMessageStr( stripCtcpWrapper( message ) ) ); + + actionStr = getActionStr( stripCtcpWrapper( message ) ); + } + + /** + * Returns the action of this CTCP. Use getMessage() to retreive + * the payload of the action. + * + * @return The action specified by the CTCP message + */ + public String getAction() + { + return actionStr; + } + + /** + * Given a stripped CTCP message, returns the ctcp action string. + * + * @param msg Message to be parsed into an action + * @return Action string from message + */ + public static String getActionStr( String msg ) + { + StringTokenizer tokens = new StringTokenizer( msg ); + return tokens.nextToken(); + } + + public static String getMessageStr( String msg ) + { + String acn = getActionStr( msg ); + return msg.substring( acn.length() ).trim(); + } + + /** + * If the string is wrapped with CTCP signal chars (\001) returns + * true. + * + * @param msg String to check whether it's a CTCP message or not + * @return True or false if it's a CTCP message + */ + public static boolean isCtcpString( String msg ) + { + return msg.charAt(0) == '\001' && msg.charAt(msg.length()-1) == '\001'; + } + + /** + * Strips a CTCP wrapper, if there is one. + * + * @param msg String to be stripped + * @return Stripped string + */ + public static String stripCtcpWrapper( String msg ) + { + if( isCtcpString( msg ) ) + { + return msg.substring( 1, msg.length()-1 ); + } + else + { + return msg; + } + } + + /** + * Dysfunctional. Returns dat immediatly. + */ + /*public static byte[] escapeMsg( byte[] dat ) + { + return dat; + }*/ + + /** + * Dysfunctional. Returns dat immediatly. + */ + /*public static byte[] unEscapeMsg( byte[] dat ) + { + return dat; + }*/ +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpNotice.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpNotice.java new file mode 100644 index 000000000..e40c0a01a --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpNotice.java @@ -0,0 +1,131 @@ +package f00f.net.irc.martyr.commands; + +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.util.FullNick; + +/** + * This facilitates the sending and receiving of CTCP messages. Upon + * receiving a message, MessageCommand checks to see if it is a CTCP, + * and if it is, it instantiates this class instead of a + * MessageCommand. You can then use the getAction() and getMessage() + * methods to retreive the action and payload, respectively. + * + * @see NoticeCommand + */ +public class CtcpNotice extends NoticeCommand +{ + private String actionStr; + + /** + * Use this to send a CTCP message. This simply wraps the string + * with the CTCP tags, \001. + * + * @param dest Target of CTCP message + * @param message Actual CTCP message + */ + public CtcpNotice( String dest, String message ) + { + super( dest, "\001" + message + "\001" ); + } + + public CtcpNotice( String dest, String action, String message ) + { + this( dest, action + " " + message ); + + actionStr = action; + } + + /** + * This is only to be called by MessageCommand, as a way of + * receiving a Ctcp message. It strips the \001's off and holds + * the message left over. + * + * @param from Nick that sent the message + * @param dest Target of the CTCP message + * @param message Actual CTCP message + */ + protected CtcpNotice( FullNick from, String dest, String message ) + { + super( from, dest, getMessageStr( stripCtcpWrapper( message ) ) ); + + actionStr = getActionStr( stripCtcpWrapper( message ) ); + } + + /** + * Returns the action of this CTCP. Use getMessage() to retreive + * the payload of the action. + * + * @return The action specified by the CTCP message + */ + public String getAction() + { + return actionStr; + } + + /** + * Given a stripped CTCP message, returns the ctcp action string. + * + * @param msg Message to be parsed into an action + * @return Action string from message + */ + public static String getActionStr( String msg ) + { + StringTokenizer tokens = new StringTokenizer( msg ); + return tokens.nextToken(); + } + + public static String getMessageStr( String msg ) + { + String acn = getActionStr( msg ); + return msg.substring( acn.length() ).trim(); + } + + /** + * If the string is wrapped with CTCP signal chars (\001) returns + * true. + * + * @param msg String to check whether it's a CTCP message or not + * @return True or false if it's a CTCP message + */ + public static boolean isCtcpString( String msg ) + { + return msg.charAt(0) == '\001' && msg.charAt(msg.length()-1) == '\001'; + } + + /** + * Strips a CTCP wrapper, if there is one. + * + * @param msg String to be stripped + * @return Stripped string + */ + public static String stripCtcpWrapper( String msg ) + { + if( isCtcpString( msg ) ) + { + return msg.substring( 1, msg.length()-1 ); + } + else + { + return msg; + } + } + + /** + * Dysfunctional. Returns dat immediatly. + */ + /*public static byte[] escapeMsg( byte[] dat ) + { + return dat; + }*/ + + /** + * Dysfunctional. Returns dat immediatly. + */ + /*public static byte[] unEscapeMsg( byte[] dat ) + { + return dat; + }*/ +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/InviteCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/InviteCommand.java new file mode 100644 index 000000000..9010a4322 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/InviteCommand.java @@ -0,0 +1,90 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; +import f00f.net.irc.martyr.util.ParameterIterator; + +/** + * @author Morgan Christiansson + */ +public class InviteCommand extends AbstractCommand { + + private String _channel; + private String _nick; + private FullNick _user; + + /** For use as a factory */ + public InviteCommand() + { + _channel = null; + _nick = null; + _user = null; + } + + private InviteCommand(FullNick user, String nick, String channel) + { + _user = user; + _nick = nick; + _channel = channel; + } + + public InviteCommand(String nick, String channel) + { + _nick = nick; + _channel = channel; + } + + public InviteCommand(FullNick nick, String channel) + { + this(nick.getNick(), channel); + } + + /* (non-Javadoc) + * @see f00f.net.irc.martyr.Command#parse(java.lang.String, java.lang.String, java.lang.String) + */ + public InCommand parse(String prefix, String identifier, String params) + { + ParameterIterator iter = new ParameterIterator(params); + return new InviteCommand( new FullNick( prefix ), (String)iter.next(), (String)iter.next() ); + } + + /* (non-Javadoc) + * @see f00f.net.irc.martyr.commands.AbstractCommand#getIrcIdentifier() + */ + public String getIrcIdentifier() + { + return "INVITE"; + } + + /* (non-Javadoc) + * @see f00f.net.irc.martyr.commands.AbstractCommand#renderParams() + */ + public String renderParams() + { + return _nick+" "+_channel; + } + + /** + * @return The channel invited to. */ + public String getChannel() + { + return _channel; + } + + /** + * @return The nick sending the invite. + */ + public String getNick() + { + return _nick; + } + + /** + * @return The user the invite is sent to. + */ + public FullNick getUser() + { + return _user; + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/IsonCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/IsonCommand.java new file mode 100644 index 000000000..8df571a8e --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/IsonCommand.java @@ -0,0 +1,144 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.CommandRegister; + +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Defines the ISON command, which is used to determine if a user or a list of users is online. + * + * @author Daniel Henninger + */ +public class IsonCommand extends AbstractCommand +{ + + public static final String IDENTIFIER_PRIMARY = "ISON"; + public static final String IDENTIFIER_SECONDARY = "303"; + + /* List of nicks that we will check for online status */ + List nicks = new ArrayList(); + + /* Destination nick */ + String dest = null; + + /** + * No parameter passed to the ISON is not valid. This is used for factories. + */ + public IsonCommand() + { + // Nothing to do + } + + /** + * Check online status of a single nickname. + * + * @param nick Nick you want to check the online status of. + */ + public IsonCommand(String nick) + { + this.nicks.add(nick); + } + + public IsonCommand(String dest, String nick) { + this.dest = dest; + this.nicks.add(nick); + } + + /** + * Check online status of a number of nicknames. + * + * @param nicks List of nicks you want to check the online status of. + */ + public IsonCommand(List nicks) + { + this.nicks.addAll(nicks); + } + + public IsonCommand(String dest, List nicks) { + this.dest = dest; + this.nicks.addAll(nicks); + } + + /** + * @see AbstractCommand#parse(String, String, String) + */ + public InCommand parse(String prefix, String identifier, String params) + { + // when the command is used as a reply, the nick is parameter 0 and the rest are parameter 1. + if ( identifier.equals( IDENTIFIER_SECONDARY ) ) { + String nickParam = getParameter(params, 1); + List nicks = Arrays.asList(nickParam.split(" ")); + return new IsonCommand(getParameter(params, 0), nicks); + } + else { + String nickParam = getParameter(params, 0); + List nicks = Arrays.asList(nickParam.split(" ")); + return new IsonCommand(nicks); + } + } + + /** + * @see f00f.net.irc.martyr.commands.AbstractCommand#renderParams() + */ + public String renderParams() + { + String ret = ""; + if (nicks.size() > 0) { + Boolean isFirst = true; + for (String nick : nicks) { + if (isFirst) { + ret = ret + nick; + isFirst = false; + } + else { + ret = ret + " " + nick; + } + } + } + return ret; + } + + /** + * @see f00f.net.irc.martyr.Command#getIrcIdentifier() + */ + public String getIrcIdentifier() + { + // + // This command uses "ISON" on outgoing, so that is why we use + // "ISON" here instead of "303". + // + return IDENTIFIER_PRIMARY; + } + + /** + * @see AbstractCommand#selfRegister(f00f.net.irc.martyr.CommandRegister) + */ + public void selfRegister(CommandRegister commandRegister) + { + commandRegister.addCommand( IDENTIFIER_PRIMARY, this ); + commandRegister.addCommand( IDENTIFIER_SECONDARY, this ); + } + + /** + * Retrieves the target of the ISON command + * + * @return Target of command + */ + public String getDest() { + return dest; + } + + /** + * Retrieves the list of nicks that are online after an ISON command + * + * @return List of online nicks + */ + public List getNicks() + { + return nicks; + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/JoinCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/JoinCommand.java new file mode 100644 index 000000000..32f2d1e75 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/JoinCommand.java @@ -0,0 +1,131 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.util.FullNick; +import java.util.logging.Logger; + + +/** + * Defines JOIN command. + */ +public class JoinCommand extends AbstractCommand +{ + + static Logger log = Logger.getLogger(JoinCommand.class.getName()); + + private String channel; + private String secret; + private FullNick user; + + /** For use as a factory */ + public JoinCommand() + { + this.user = null; + this.channel = null; + this.secret = null; + } + + /** + * This constructor is used with an incoming JOIN command from the server. + * + * @param user User that joined the channel + * @param channel Channel that was joined + */ + private JoinCommand( FullNick user, String channel ) + { + this.user = user; + this.channel = channel; + this.secret = null; + } + + /** + * This constructor is used to make a request to join a channel that + * requires a secret key to join. + * + * @param channel The channel + * @param secret The secret key required to enter the channel, or null of + * none. + */ + public JoinCommand( String channel, String secret ) + { + this.secret = secret; + this.user = null; + this.channel = channel; + } + + /** + * This constructor is used to make a request to join a channel. + * + * @param channel Channel that will be joined + */ + public JoinCommand( String channel ) + { + this.secret = null; + this.user = null; + this.channel = channel; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new JoinCommand( new FullNick( prefix ), getParameter( params, 0 ) ); + } + + public String getIrcIdentifier() + { + return "JOIN"; + } + + public String renderParams() + { + if( secret == null ) + return channel; + else + return channel + " " + secret; + } + + public String getChannel() + { + return channel; + } + + public String getSecret() + { + return secret; + } + + public FullNick getUser() + { + return user; + } + + public boolean weJoined( ClientState state ) + { + return user.equals( state.getNick() ); + } + + public boolean updateClientState( ClientState state ) + { + if( weJoined( state ) ) + { + // We've joined a group. + //log.debug("JOIN: We've joined " + channel); + state.addChannel( channel ); + return true; + } + else + { + // Someone else joined the group. + //log.debug("JOIN: " + user + " joined " + channel); + // 1) Grab group + Channel channelObj = state.getChannel( channel ); + // 2) Add user + channelObj.addMember( user, this ); + return true; + } + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/KickCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/KickCommand.java new file mode 100644 index 000000000..96b2731e1 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/KickCommand.java @@ -0,0 +1,110 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.util.FullNick; +import java.util.logging.Logger; + + +/** + * Defines KICK command. + */ +public class KickCommand extends AbstractCommand +{ + + static Logger log = Logger.getLogger(KickCommand.class.getName()); + + private String channel; + private FullNick userKicker; + private FullNick userKicked; + private String comment; + + /** For use as a factory */ + public KickCommand() + { + this( null, null, null, null ); + } + + public KickCommand( FullNick userKicker, String channel, + String userKicked, String comment ) + { + this.userKicker = userKicker; + this.channel = channel; + this.userKicked = new FullNick( userKicked ); + this.comment = comment; + } + + public KickCommand( String channel, String userToKick, String comment ) + { + this( null, channel, userToKick, comment ); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new KickCommand( + new FullNick( prefix ), + getParameter( params, 0 ), + getParameter( params, 1 ), + getParameter( params, 2 ) + ); + } + + public String getIrcIdentifier() + { + return "KICK"; + } + + public String renderParams() + { + return channel + " " + userKicked + " :" + comment; + } + + public String getChannel() + { + return channel; + } + + public FullNick getKicker() + { + return userKicker; + } + + public FullNick getKicked() + { + return userKicked; + } + + public String getComment() + { + return comment; + } + + public boolean kickedUs( ClientState state ) + { + return userKicked.equals( state.getNick() ); + } + + public boolean updateClientState( ClientState state ) + { + if( kickedUs( state ) ) + { + // We've been kicked. + //log.debug("KICK: We've been kicked " + channel); + state.removeChannel( channel ); + return true; + } + else + { + // Someone else was kicked. + //log.debug("KICK: " + userKicked.getNick() + " kicked " + channel); + // 1) Grab group + Channel channelObj = state.getChannel( channel ); + channelObj.removeMember( userKicked, this ); + return true; + } + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/MessageCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/MessageCommand.java new file mode 100644 index 000000000..3d66f7c21 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/MessageCommand.java @@ -0,0 +1,127 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.util.FullNick; + + +/** + * Defines the PRIVMSG command. Messages can be sent to groups or to users. + */ +public class MessageCommand extends AbstractCommand +{ + + private FullNick from; + private String dest; + private String message; + + + /** Factory */ + public MessageCommand() + { + from = null; + dest = null; + message = null; + } + + /** + * Used to send a message. + * + * @param dest Target for message + * @param message Message to be sent + */ + public MessageCommand( String dest, String message ) + { + this( null, dest, message ); + } + + /** + * Used to send a message. + * + * @param dest Target for message + * @param message Message to be sent + */ + public MessageCommand( FullNick dest, String message ) + { + this( dest.getNick(), message ); + } + + public MessageCommand( FullNick source, String dest, String message ) + { + this.from = source; + this.dest = dest; + this.message = message; + } + + /** + * Parses a string and produces a formed command object, if it can. + * Should return null if it cannot form the command object. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + FullNick from; + if( prefix == null || prefix.trim().length() == 0 ) + { + from = null; + } + else + { + from = new FullNick( prefix ); + } + String dest = getParameter( params, 0 ); + String msg = getParameter( params, 1 ); + + if( CtcpMessage.isCtcpString( msg ) ) + { + return new CtcpMessage( from, dest, msg ); + } + + return new MessageCommand( from, dest, msg ); + } + + /** + * Returns the string IRC uses to identify this command. Examples: + * NICK, PING, KILL, 332 + */ + public String getIrcIdentifier() + { + return "PRIVMSG"; + } + + /** + * Renders the parameters of this command. + */ + public String renderParams() + { + return dest + " :" + message; + } + + public FullNick getSource() + { + return from; + } + + public String getDest() + { + return dest; + } + + public String getMessage() + { + return message; + } + + /** + * Returns true if the message is both private and for us. + * + * @param state Client state to compare with + * @return True or false if this is a private message to us + */ + public boolean isPrivateToUs( ClientState state ) + { + return state.getNick().equals( dest ); + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ModeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ModeCommand.java new file mode 100644 index 000000000..b3c3e19ef --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ModeCommand.java @@ -0,0 +1,237 @@ +package f00f.net.irc.martyr.commands; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.CommandRegister; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.Mode; +import f00f.net.irc.martyr.OutCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; +import java.util.logging.Logger; + +/** + * Defines MODE command. Since the MODE command is of two distinct + * types, this class is really more of a command mini-factory. It + * determines which type of command it is, either a UserModeCommand or + * a ChannelModeCommand. + * + */ +public class ModeCommand implements InCommand, OutCommand +{ + static Logger log = Logger.getLogger(ModeCommand.class.getName()); + + public static final String IDENTIFIER = "MODE"; + private String source; + + /** For use as a factory */ + public ModeCommand() + { + } + + public Iterator getAttributeKeys() + { + return new LinkedList().iterator(); + } + + public String getAttribute( String key ) + { + return null; + } + + public static void registerMode( Map modes, Mode mode ) + { + Character modeChar = mode.getChar(); + + if( modes.get( modeChar ) != null ) + { + log.severe("ModeCommand: Warning: Two modes with same letter: " + + modes.get( modeChar ) + " and " + mode); + } + + modes.put( modeChar, mode ); + } + + public State getState() + { + return State.REGISTERED; + } + + public void selfRegister( CommandRegister reg ) + { + reg.addCommand( IDENTIFIER, this ); + } + + public String getIrcIdentifier() + { + return IDENTIFIER; + } + + // Example + //
:repp_!bdamm@dammfine.com MODE #bytesex +oo z * repp_telnet
+ public InCommand parse( String prefix, String identifier, String params ) + { + // there are two kinds of modes. Either a channel mode, or a user + // mode. We need to figure out which we are dealing with, and + // return that. + + // TODO: Research: Should we specify delimiters other than whitespace? + StringTokenizer tokens = new StringTokenizer( params ); + + String str = tokens.nextToken(); + + //log.debug("ModeCommand: Prefix: " + prefix + " str: " + str + // + " total: " + params); + + // Malformed command. + if( str == null ) + return null; + + // Should we check to see if the string is really a channel + // that we know about? + if( Channel.isChannel( str ) ) + { + return new ChannelModeCommand( prefix, str, tokens ); + } + else + { + return new UserModeCommand( prefix, str, tokens ); + } + } + + /** + * Should not be called, as ModeCommand doesn't actually represent a + * command. Use UserModeCommand or ChannelModeCommand instead. + */ + public String render() + { + throw new IllegalStateException("Don't try to send ModeCommand!"); + } + + public void setSourceString( String source ) + { + this.source = source; + } + + public String getSourceString() + { + return source; + } + + /** + * Does nothing, as this is a factory command. + */ + public boolean updateClientState( ClientState cs ) + { + // Nothing here, move on. + return false; + } + + public String toString() + { + return "ModeCommand"; + } + + /** Takes a mode string, such as: '+ooo A B C' or '+o A +o B' or even + * '+o-o A B' and returns a List containing Mode objects that + * correspond to the modes specified. + * + * @param modes is a Map of Character to Mode objects. + * @param tokens is the sequence of tokens making up the parameters of + * the command. + * @return List of modes + */ + public List parseModes( Map modes, StringTokenizer tokens ) + { + LinkedList results = new LinkedList(); + + while( true ) + { + if( tokens.hasMoreTokens() ) + { + parseOneModeSet( modes, tokens, results ); + } + else + { + return results; + } + } + } + + /** + * Parses one group of modes. '+ooo A B C' and not '+o A +o B'. It + * will parse the first group it finds and will ignore the rest. + * + * @param modes Map of character to Mode objects. + * @param tokens Sequence of tokens making up the parameters of the command. + * @param results List of Mode results to be filled in + */ + private void parseOneModeSet( Map modes, StringTokenizer tokens, List results ) + { + // A list of modes that we have. + LinkedList localModes = new LinkedList(); + + Mode.Sign sign = Mode.Sign.NOSIGN; + String chars = tokens.nextToken(); + + int stop = chars.length(); + for( int i = 0; i < stop; ++i ) + { + char lookingAt = chars.charAt( i ); + if( lookingAt == '+' ) + sign = Mode.Sign.POSITIVE; + else if( lookingAt == '-' ) + sign = Mode.Sign.NEGATIVE; + else if( lookingAt == ':' ) + // This is to get around a bug in some ircds + continue; + else + { + // A real mode character! + Mode mode = modes.get( lookingAt ); + if( mode == null ) + { + //TODO: Is there some way we can figure out if the mode + // we don't know anything about needs a parameter? + // Things get messy if it does need a parameter, and we + // don't eat the string. + //log.severe("ModeCommand: Unknown mode: " + lookingAt); + } + else + { + mode = mode.newInstance(); + mode.setSign( sign ); + localModes.add( mode ); + } + } + } + + // Now we know what modes are specified, and whether they are + // positive or negative. Now we need to fill in the parameters for + // any that require parameters, and place the results in the result + // list. + for (Mode localMode : localModes) { + /* + * What we do if the server doesn't pass us a parameter + * for a mode is rather undefined - except that we don't + * want to run off the end of the tokens. So we just + * ignore it. The problem is that we don't always know + * when a server is going to send us a parameter or not. + * We can only hope that servers don't send ambiguous + * masks followed by more modes instead of a parameter. + */ + if (localMode != null && localMode.requiresParam() && tokens.hasMoreTokens()) { + localMode.setParam(tokens.nextToken()); + } + + results.add(localMode); + } + } +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NamesCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NamesCommand.java new file mode 100644 index 000000000..6f0a9ed5d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NamesCommand.java @@ -0,0 +1,77 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.OutCommand; + +import java.util.List; +import java.util.ArrayList; + +/** + * Defines the NAMES command, which is used to get the members of certain channels, or all of them. + * + * @author Daniel Henninger + */ +public class NamesCommand implements OutCommand +{ + + /* List of channels we will request membership of. */ + List channels = new ArrayList(); + + /** + * No parameter passed to the NAMES command represents a request for all channels. + */ + public NamesCommand() + { + // Nothing to do + } + + /** + * Request the membership of a single channel. + * + * @param channel Channel you want to request membership of. + */ + public NamesCommand(String channel) + { + this.channels.add(channel); + } + + /** + * Request the membership of multiple channels. + * + * @param channels List of channels you want to retrieve the membership list of. + */ + public NamesCommand(List channels) + { + this.channels.addAll(channels); + } + + /** + * @see f00f.net.irc.martyr.OutCommand#render() + */ + public String render() + { + String ret = getIrcIdentifier(); + if (channels.size() > 0) { + ret = ret + " "; + Boolean isFirst = true; + for (String channel : channels) { + if (isFirst) { + ret = ret + channel; + isFirst = false; + } + else { + ret = ret + "," + channel; + } + } + } + return ret; + } + + /** + * @see f00f.net.irc.martyr.Command#getIrcIdentifier() + */ + public String getIrcIdentifier() + { + return "NAMES"; + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NickCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NickCommand.java new file mode 100644 index 000000000..6cdcb0224 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NickCommand.java @@ -0,0 +1,97 @@ +/* + * Original version: Ben Damm + * Changes by: Mog + * - added getOldNick + * */ +package f00f.net.irc.martyr.commands; + +import java.util.Enumeration; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.clientstate.Member; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Defines NICK command. + */ +public class NickCommand extends AbstractCommand +{ + + private FullNick oldNick; + private FullNick newNick; + + /** For use as a factory */ + public NickCommand() + { + this( null, null ); + } + + public NickCommand( FullNick oldNick, FullNick newNick ) + { + this.oldNick = oldNick; + this.newNick = newNick; + } + + public NickCommand( String newNick ) + { + this( null, new FullNick( newNick ) ); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NickCommand( new FullNick( prefix ), new FullNick ( getParameter( params, 0 ) ) ); + } + + public String getIrcIdentifier() + { + return "NICK"; + } + + public String renderParams() + { + return getNick(); + } + + public String getNick() + { + return newNick.getNick(); + } + + public String getOldNick() + { + return oldNick.getNick(); + } + + public boolean updateClientState( ClientState state ) + { + // Does this apply to us? + if( oldNick.equals( state.getNick() ) ) + { + state.setNick( newNick ); + return true; + } + else + { + // Ok, so we need to change someone's nick. + // This needs to occur for each member with that nick in each + // channel that we are in. Just use Member.setNick for each + // occurance. + // Note: I do not believe this code has received a vigorous + // test. + Enumeration channels = state.getChannels(); + while( channels.hasMoreElements() ) + { + Channel channel = (Channel)channels.nextElement(); + Member member = channel.findMember( oldNick.getNick() ); + if( member != null ) + member.setNick( newNick ); + } + } + return false; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NoticeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NoticeCommand.java new file mode 100644 index 000000000..958dcc44f --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NoticeCommand.java @@ -0,0 +1,129 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.util.FullNick; + + +/** + * Defines the NOTICE command. + */ +public class NoticeCommand extends AbstractCommand +{ + + private FullNick from; + private String dest; + private String notice; + + /** Factory */ + public NoticeCommand() + { + from = null; + dest = null; + notice = null; + } + + public NoticeCommand( String notice ) + { + this.notice = notice; + } + + public NoticeCommand( String dest, String notice ) + { + this(null, dest, notice); + } + + public NoticeCommand( FullNick dest, String notice ) + { + this(dest.getNick(), notice); + } + + public NoticeCommand( FullNick source, String dest, String notice ) { + this.from = source; + this.dest = dest; + this.notice = notice; + } + + public State getState() + { + return State.UNKNOWN; + } + + /** + * Parses a string and produces a formed command object, if it can. + * Should return null if it cannot form the command object. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + FullNick from; + if( prefix == null || prefix.trim().length() == 0 ) + { + from = null; + } + else + { + from = new FullNick( prefix ); + } + String dest = getParameter( params, 0 ); + String msg = getParameter( params, 1 ); + + if( CtcpNotice.isCtcpString( msg ) ) + { + return new CtcpNotice( from, dest, msg ); + } + + return new NoticeCommand( from, dest, msg ); + } + + /** + * Returns the string IRC uses to identify this command. Examples: + * NICK, PING, KILL, 332 + */ + public String getIrcIdentifier() + { + return "NOTICE"; + } + + /** + * Renders the parameters of this command. + */ + public String renderParams() + { + if (dest != null) { + return dest + " :" + notice; + } + else { + return ":" + notice; + } + } + + public FullNick getFrom() + { + return from; + } + + public String getDest() + { + return dest; + } + + public String getNotice() + { + return notice; + } + + /** + * Returns true if the message is both private and for us. + * + * @param state Client state to compare with + * @return True or false if this is a private message to us + */ + public boolean isPrivateToUs( ClientState state ) + { + return state.getNick().equals( dest ); + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PartCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PartCommand.java new file mode 100644 index 000000000..b27ed6dd2 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PartCommand.java @@ -0,0 +1,126 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.util.FullNick; + +/** + *

Defines PART command. If the part command is from us, we should + * remove that channel from the list of channels. If the part command + * is from someone else, we should remove that user from the list of + * users for that channel. + */ + +public class PartCommand extends AbstractCommand +{ + + private String reason; + private String channel; + private FullNick user; + + /** For use as a factory */ + public PartCommand() + { + this( null, null, null ); + } + + /** + * For use as an incoming command. + * + * @param user User that is parting + * @param channel Channel that the user is parting from + * @param reason Reason for part + */ + public PartCommand( FullNick user, String channel, String reason ) + { + this.user = user; + this.reason = reason; + this.channel = channel; + } + + /** + * For use as an outgoing command. + * + * @param channel Channel that we are parting from + * @param reason Reason we are parting + */ + public PartCommand( String channel, String reason ) + { + this( null, channel, reason ); + } + + /** + * For use as an outgoing command. Part with no reason. + * + * @param channel Channel that we are parting from + */ + public PartCommand( String channel ) + { + this( null, channel, null ); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new PartCommand( new FullNick( prefix ), getParameter( params, 0 ), getParameter( params, 1 ) ); + } + + public String getIrcIdentifier() + { + return "PART"; + } + + public String renderParams() + { + if( reason != null ) + return channel + " :" + reason; + else + return channel; + } + + public String getReason() + { + return reason; + } + + public String getChannel() + { + return channel; + } + + public FullNick getUser() + { + return user; + } + + /** Takes client state action. If we are parting, then remove that + * channel from our list of channels. If someone else is parting, + * remove them from the channel they are parting from. + */ + public boolean updateClientState( ClientState state ) + { + // We parted + if( user.equals( state.getNick() ) ) + { + state.removeChannel( channel ); + return true; + } + else + { + // Someone else parted. + + // 1) Grab channel + Channel chanObj = state.getChannel( channel ); + + // 2) Remove user + chanObj.removeMember( user, this ); + return true; + } + + } + +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PassCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PassCommand.java new file mode 100644 index 000000000..da1e63cd5 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PassCommand.java @@ -0,0 +1,33 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.OutCommand; + +/** + * Defines PASS command, optional part of the handshake to register on the network. + * @author Daniel Henninger + */ +public class PassCommand implements OutCommand +{ + private String pass; + + public static final String IDENTIFIER = "PASS"; + + /** + * @param pass the password for the user who is authenticating + * */ + public PassCommand(String pass) + { + this.pass = pass; + } + + public String render() + { + return IDENTIFIER + " " + pass; + } + + public String getIrcIdentifier() + { + return IDENTIFIER; + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PingCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PingCommand.java new file mode 100644 index 000000000..01c68cb90 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PingCommand.java @@ -0,0 +1,67 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; + + +/** + * Defines the PING command. At this point, PINGs only come in from + * the server, so all we need to do is capture the parameters. + */ +public class PingCommand extends AbstractCommand +{ + + private String pingSource; + + /** Factory */ + public PingCommand() + { + pingSource = null; + } + + public PingCommand( String source ) + { + pingSource = source; + } + + public State getState() + { + return State.UNKNOWN; + } + + /** + * Parses a string and produces a formed command object, if it can. + * Should return null if it cannot form the command object. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + String str = getParameter( params, 0 ); + return new PingCommand( str ); + } + + /** + * Returns the string IRC uses to identify this command. Examples: + * NICK, PING, KILL, 332 + */ + public String getIrcIdentifier() + { + return "PING"; + } + + /** + * Renders the parameters of this command. + */ + public String renderParams() + { + return ":" + pingSource; + } + + // ===== Ping-specific methods ======================================= + public String getPingSource() + { + return pingSource; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PongCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PongCommand.java new file mode 100644 index 000000000..bfd22531a --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PongCommand.java @@ -0,0 +1,39 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; + + +/** + * Defines the PONG command. At this point, PONGs can only be sent to + * the server, so all we need to do is provide render(). + */ +public class PongCommand extends PingCommand +{ + + public PongCommand( String dest ) + { + super( dest ); + } + + /** + * PONG shouldn't be sent to us. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + throw new UnsupportedOperationException("PONG is not an incommand."); + } + + public String getIrcIdentifier() + { + return "PONG"; + } + + // ===== Pong-specific methods ======================================= + public String getPongDest() + { + return getPingSource(); + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/QuitCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/QuitCommand.java new file mode 100644 index 000000000..e12a2520d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/QuitCommand.java @@ -0,0 +1,132 @@ +package f00f.net.irc.martyr.commands; + +import java.util.Enumeration; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.util.FullNick; + +/** + *

Defines QUIT command. The QUIT command asks the irc server to + * disconnect us, and we can optionally give a reason. The QUIT + * command is also received by us if someone on a channel we are on + * quits.

+ * + *

What should be done to signal to the framework that the + * disconnection that should come from the server is legit, and we + * shouldn't try to re-connecet? For now it will be assumed that the + * user of the framework will signal all the appropriate classes that + * a legit disconnection will happen (ie AutoRegister which will try + * to re-connect otherwise).

+ */ +public class QuitCommand extends AbstractCommand +{ + //static Logger log = Logger.getLogger(QuitCommand.class); + + private String reason; + private FullNick user; + + /** For use as a factory */ + public QuitCommand() + { + this( null, null ); + } + + /** + * For use as an incoming command. + * + * @param user User that has quit + * @param reason Specified reason for quitting + */ + public QuitCommand( FullNick user, String reason ) + { + this.user = user; + this.reason = reason; + } + + /** + * For use as an outgoing command. + * + * @param reason Specified reason for quitting + */ + public QuitCommand( String reason ) + { + this( null, reason ); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new QuitCommand( new FullNick( prefix ), getParameter( params, 0 ) ); + } + + public String getIrcIdentifier() + { + return "QUIT"; + } + + public String renderParams() + { + return ":" + reason; + } + + public String getReason() + { + return reason; + } + + public FullNick getUser() + { + return user; + } + + /** + * Returns true if we are the ones quitting. + * + * @param state Client state we are checking against + * @return True or false if the quit is us quitting + */ + public boolean isOurQuit( ClientState state ) + { + return user.equals( state.getNick() ); + } + + /** If we are quitting, we won't be worrying about our client state. + * If someone else is leaving, then remove them from all the groups + * they are in. + */ + public boolean updateClientState( ClientState state ) + { + //log.debug( "Nick: " + state.getNick().toString() ); + if( isOurQuit(state) ) + { + // We've quit + //log.debug("QUIT: We've quit: " + reason); + + // What should we do with the client state here? + return true; + } + else + { + // Someone else quit. We need to remove them from each group + // they are in. + //log.debug("QUIT: " + user + " quit: " + reason); + + // 1) Grab channels + Enumeration channelNames = state.getChannelNames(); + while( channelNames.hasMoreElements() ) + { + String chanName = channelNames.nextElement().toString(); + + // 2) Remove from group. + Channel channelObj = state.getChannel( chanName); + channelObj.removeMember( user, this ); + } + + return true; + } + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/RawCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/RawCommand.java new file mode 100644 index 000000000..b7375e92f --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/RawCommand.java @@ -0,0 +1,58 @@ +package f00f.net.irc.martyr.commands; + +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.OutCommand; + +public class RawCommand implements OutCommand +{ + + private String sourceString; + private String ident; + + /** + * Tries to use the first "word" in the command as the identifier. + * Using this constructor is not recommended. + * + * @param raw Raw command to send to server + */ + public RawCommand( String raw ) + { + sourceString = raw; + StringTokenizer tokens = new StringTokenizer( raw ); + ident = tokens.nextToken(); + } + + /** + * The rendered command will be identifier + " " + + * parameters. This constructure simply allows a correct + * response to the getIrcIdentifier method. + * + * @param identifier Command identifier + * @param parameters Parameters to pass + */ + public RawCommand( String identifier, String parameters ) + { + ident = identifier; + sourceString = ident + " " + parameters; + } + + /** + * Returns the identifier, if supplied, or null. + */ + public String getIrcIdentifier() + { + return ident; + } + + /** + * Simply returns the string given in the constructor. + */ + public String render() + { + return sourceString; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/TopicCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/TopicCommand.java new file mode 100644 index 000000000..42e3d0421 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/TopicCommand.java @@ -0,0 +1,80 @@ +package f00f.net.irc.martyr.commands; + +import java.util.Date; + +import f00f.net.irc.martyr.CommandRegister; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; + +public class TopicCommand extends AbstractCommand +{ + //static Logger log = Logger.getLogger(TopicCommand.class); + + private String channel; + private String topic; + + public static final String IDENTIFIER_PRIMARY = "TOPIC"; + public static final String IDENTIFIER_SECONDARY = "332"; + + public TopicCommand() + { + this( null, null ); + } + + public TopicCommand( String channel, String topic ) + { + this.channel = channel; + this.topic = topic; + } + + public String getIrcIdentifier() + { + // + // This command uses "TOPIC" on outgoing, so that is why we use + // "TOPIC" here instead of "332". + // + return IDENTIFIER_PRIMARY; + } + + public void selfRegister( CommandRegister commandRegister ) + { + commandRegister.addCommand( IDENTIFIER_PRIMARY, this ); + commandRegister.addCommand( IDENTIFIER_SECONDARY, this ); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + // when the command is used as a reply, the nick is parameter 0. + if( identifier.equals( IDENTIFIER_SECONDARY ) ) + return new TopicCommand( getParameter(params, 1), getParameter(params, 2) ); + else + return new TopicCommand( getParameter(params, 0), getParameter(params, 1) ); + } + + public String renderParams() + { + return getChannel() + " :" + getTopic(); + } + + public String getTopic() + { + return topic; + } + + public String getChannel() + { + return channel; + } + + public boolean updateClientState( ClientState state ) + { + //log.debug("Topic: Channel: " + channel); + Channel chan = state.getChannel( channel ); + chan.setTopic( topic ); + chan.setTopicDate( new Date() ); + return true; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UnknownCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UnknownCommand.java new file mode 100644 index 000000000..6ecd4bc4d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UnknownCommand.java @@ -0,0 +1,38 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; + + +/** + * Some unknown command, for which there is no factory. This is a + * special case command, created by IRCConnection if it can't find a + * proper command object. + */ +public class UnknownCommand extends AbstractInCommand +{ + + public State getState() + { + return State.UNKNOWN; + } + + /** + * Never parsed. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + throw new UnsupportedOperationException("UnknownCommand does no parsing."); + } + + /** + * Unknown, so we don't know what the identifier is ahead of time. + */ + public String getIrcIdentifier() + { + return null; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserCommand.java new file mode 100644 index 000000000..ac7796f7c --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserCommand.java @@ -0,0 +1,46 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.IRCConnection; +import f00f.net.irc.martyr.OutCommand; +/** + * Defines USER command, part of the handshake to register on the + * network. + */ +public class UserCommand implements OutCommand +{ + + private String name; + private String user; + private String someA; // Might be a mode on some networks + private String someB; // might be ignored + + public static final String IDENTIFIER = "USER"; + + /** + * @param user the login name on the computer the client is on + * @param name the purported full name of the user, can be anything. + * @param connection the connection the user command is affiliated with + * */ + public UserCommand( String user, String name, IRCConnection connection ) + { + this.name = name; + this.user = user; + //localhost = connection.getLocalhost(); + //remotehost = connection.getRemotehost(); + someA = "0"; // Can be 0|4|8, with 4=+w, 8=+i + someB = connection.getRemotehost(); // ignored, apparently + } + + public String render() + { + return IDENTIFIER + " " + user + " " + someA + " " + someB + " :" + name; + } + + public String getIrcIdentifier() + { + return IDENTIFIER; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserModeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserModeCommand.java new file mode 100644 index 000000000..1190ed64a --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserModeCommand.java @@ -0,0 +1,99 @@ +package f00f.net.irc.martyr.commands; + +import java.util.HashMap; +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.Mode; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.modes.user.InvisibleMode; +import f00f.net.irc.martyr.util.FullNick; +import java.util.logging.Logger; + +/** + * Defines a user MODE command. + */ +public class UserModeCommand extends ModeCommand +{ + static Logger log = Logger.getLogger(ModeCommand.class.getName()); + + private FullNick user; + private FullNick sender; + //private List modes; + + private static HashMap modeTypes; + + public UserModeCommand( String prefix, String userStr, StringTokenizer tokens ) + { +// System.out.println( prefix ); + sender = new FullNick( prefix ); + user = new FullNick( userStr ); + + if( !sender.equals( user ) ) + { + log.severe("UserModeCommand: Odd: mode change for a user that isn't us."); + return; + } + + makeModeTypes(); + + //modes = parseModes( modeTypes, tokens ); + +// System.out.println( modes ); + } + + private void makeModeTypes() + { + if( modeTypes == null ) + { + modeTypes = new HashMap(); + + // Add new mode types here + registerMode( modeTypes, new InvisibleMode() ); + } + } + + + /** + * Should not be called, as ModeCommand does the parsing and instantiation + * of this class. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + throw new IllegalStateException( "Don't call this method!" ); + } + + public String render() + { + throw new UnsupportedOperationException("Can't send user modes, yet." ); + } + + public FullNick getUser() + { + return user; + } + + public FullNick getSender() { + return sender; + } + + { + //log.debug("TODO: UserModeCommand: Can't send"); + //log.debug("TODO: UserModeCommand: Does not update client state"); + } + + public boolean updateClientState( ClientState state ) + { + // TODO implement + return false; + } + + public String toString() + { + return "UserModeCommand"; + } + + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WelcomeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WelcomeCommand.java new file mode 100644 index 000000000..ecbe9b1ac --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WelcomeCommand.java @@ -0,0 +1,125 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.CommandRegister; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.util.FullNick; +import f00f.net.irc.martyr.util.ParameterIterator; +import java.util.logging.Logger; + + +/** + * Defines the commands that a server issues to welcome us. These are + * identified with 001, 002... etc. These commands are only received + * after we register, unlike the NOTICE command. + */ +public class WelcomeCommand extends AbstractInCommand +{ + static Logger log = Logger.getLogger(WelcomeCommand.class.getName()); + + private String notice; + private String nick; + + /** Factory */ + public WelcomeCommand() + { + this( null, null ); + } + + /** + * Used by parse to create an instance of WelcomeCommand. + * + * @param nick Nick that send the welcome + * @param notice Notice that was sent + * */ + public WelcomeCommand( String nick, String notice ) + { + this.notice = notice; + this.nick = nick; + //log.debug("WelcomeCommand: Nick is: `" + nick + "'"); + //log.debug("WelcomeCommand: Notice is: `"+notice+"'"); + } + + /** + * Parses a string and produces a formed command object, if it can. + * Should return null if it cannot form the command object. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + ParameterIterator pi = new ParameterIterator( params ); + String nick = pi.next().toString(); + String notice; + if( pi.hasNext() ) + { + // We are looking at a "nick :msg" pair + notice = pi.next().toString(); + } + else + { + // There is only one parameter, a notice. + notice = nick; + nick = null; + } + if( pi.hasNext() ) + { + //log.severe("WelcomeCommand: More than two parameters, confused."); + } + + + //String str = getParameter( params, 0 ); + // + return new WelcomeCommand( nick, notice ); + } + + /** + * Sets the nick of the client state, if there is one included with + * this command. + */ + public boolean updateClientState( ClientState state ) + { + //log.debug("WelcomeCommand: updated client state with: " + new FullNick( nick )); + state.setNick( new FullNick( nick ) ); + + return true; + } + + /** + * Returns the string IRC uses to identify this command. Examples: + * NICK, PING, KILL, 332. In our case, there is no one thing. + */ + public String getIrcIdentifier() + { + return "001"; + } + + public void selfRegister( CommandRegister commandRegister ) + { + commandRegister.addCommand( "001", this ); + commandRegister.addCommand( "002", this ); + commandRegister.addCommand( "003", this ); + commandRegister.addCommand( "004", this ); + commandRegister.addCommand( "005", this ); + } + + public String getNotice() + { + return notice; + } + + /** + * @return the nick received with this command, or null if there isn't + * one. + * */ + public String getNick() + { + return nick; + } + + public String toString() + { + return "WelcomeCommand"; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WhoisCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WhoisCommand.java new file mode 100644 index 000000000..1c5dea618 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WhoisCommand.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.commands; + +import f00f.net.irc.martyr.OutCommand; + +/** + * Implements a WHOIS command, to query details about a user. + * + */ +public class WhoisCommand implements OutCommand +{ + private static final String WHOIS = "WHOIS"; + + private String target; + + /** + * @param target the nick or mask that you wish to know about. + */ + public WhoisCommand( String target ) + { + this.target = target; + } + + /** + * @return "WHOIS" + */ + public String getIrcIdentifier() + { + return WHOIS; + } + + /** + * Simply returns the string given in the constructor. + */ + public String render() + { + return WHOIS + " " + target; + } +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/AlreadyRegisteredError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/AlreadyRegisteredError.java new file mode 100644 index 000000000..736b5ebf6 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/AlreadyRegisteredError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 462 ERR_ALREADYREGISTERED + * :You may not reregister + * Returned by the server to any link which tries to change part of the registered details (such as + * password or user details from second USER message). + */ +public class AlreadyRegisteredError extends GenericError +{ + private String errorMessage; + + public AlreadyRegisteredError() + { + } + + public AlreadyRegisteredError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "462"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new AlreadyRegisteredError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CannotSendToChanError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CannotSendToChanError.java new file mode 100644 index 000000000..93793c89a --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CannotSendToChanError.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 404 ERR_CANNOTSENDTOCHAN + * <channel name> :Cannot send to channel + * Sent to a user who is either (a) not on a channel which is mode +n or (b) not a chanop (or mode +v) + * on a channel which has mode +m set and is trying to send a PRIVMSG message to that channel. + */ +public class CannotSendToChanError extends GenericError +{ + private String channel; + private String errorMessage; + + public CannotSendToChanError() + { + } + + public CannotSendToChanError(String channel, String errorMessage) + { + this.channel = channel; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "404"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new CannotSendToChanError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getChannel() + { + return channel; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CantKillServerError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CantKillServerError.java new file mode 100644 index 000000000..246bcbbe7 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CantKillServerError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 483 ERR_CANTKILLSERVER + * :You can't kill a server! + * Any attempts to use the KILL command on a server are to be refused and this + * error returned directly to the client. + */ +public class CantKillServerError extends GenericError +{ + private String errorMessage; + + public CantKillServerError() + { + } + + public CantKillServerError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "483"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new CantKillServerError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChanOPrivsNeededError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChanOPrivsNeededError.java new file mode 100644 index 000000000..366dc2b10 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChanOPrivsNeededError.java @@ -0,0 +1,48 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 482 ERR_CHANOPRIVSNEEDED + * <channel> :You're not channel operator + * Any command requiring 'chanop' privileges (such as MODE messages) must return + * this error if the client making the attempt is not a chanop on the specified + * channel. + */ +public class ChanOPrivsNeededError extends GenericError +{ + private String channel; + private String errorMessage; + + public ChanOPrivsNeededError() + { + } + + public ChanOPrivsNeededError(String channel, String errorMessage) + { + this.channel = channel; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "482"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new ChanOPrivsNeededError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getChannel() + { + return channel; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelBannedError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelBannedError.java new file mode 100644 index 000000000..7e3411b70 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelBannedError.java @@ -0,0 +1,49 @@ +/* + * ChannelBannedError.java + * + * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * See: http://www.fsf.org/copyleft/lesser.txt + */ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 474 ERR_BANNEDFROMCHAN + * <channel> :Cannot join channel (+b) + * @author Morgan Christiansson + * @version $Id: ChannelBannedError.java 85 2007-08-02 18:26:59Z jadestorm $ + * TODO: Should er rename this to BannedFromChanError to match others? + */ +public class ChannelBannedError extends GenericJoinError { + public ChannelBannedError() + { + // This one's for registering. + } + + protected ChannelBannedError( String chan, String comment ) + { + super(chan, comment); + } + + public String getIrcIdentifier() + { + return "474"; + } + + protected InCommand create( String channel, String comment) + { + return new ChannelBannedError( channel, comment ); + } +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelInviteOnlyError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelInviteOnlyError.java new file mode 100644 index 000000000..af6322b61 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelInviteOnlyError.java @@ -0,0 +1,48 @@ +/* + * ChannelInviteOnlyError.java + * + * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * See: http://www.fsf.org/copyleft/lesser.txt + */ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +/** + * Code: 473 ERR_INVITEONLYCHAN + * <channel> :Cannot join channel (+i) + * @version $Id: ChannelInviteOnlyError.java 85 2007-08-02 18:26:59Z jadestorm $ + * TODO: Should we rename this to InviteOnlyChanError to match others? + */ +public class ChannelInviteOnlyError extends GenericJoinError +{ + public ChannelInviteOnlyError() + { + // This one's for registering. + } + + protected ChannelInviteOnlyError( String chan, String comment ) + { + super(chan, comment); + } + + public String getIrcIdentifier() + { + return "473"; + } + + protected InCommand create(String channel, String comment) + { + return new ChannelInviteOnlyError( channel, comment ); + } +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelLimitError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelLimitError.java new file mode 100644 index 000000000..8e7174286 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelLimitError.java @@ -0,0 +1,50 @@ +/* + * ChannelLimitError.java + * + * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * See: http://www.fsf.org/copyleft/lesser.txt + */ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 471 ERR_CHANNELISFULL + * <channel> :Cannot join channel (+l) + * @author Morgan Christiansson + * @version $Id: ChannelLimitError.java 85 2007-08-02 18:26:59Z jadestorm $ + * TODO: Rename to ChannelIsFullError to match style of others? + */ +public class ChannelLimitError extends GenericJoinError +{ + public ChannelLimitError() + { + // This one's for registering. + } + + protected ChannelLimitError( String chan, String comment ) + { + super(chan, comment); + } + + public String getIrcIdentifier() + { + return "471"; + } + + protected InCommand create(String channel, String comment) + { + return new ChannelLimitError( channel, comment ); + } +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelWrongKeyError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelWrongKeyError.java new file mode 100644 index 000000000..099352f9b --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelWrongKeyError.java @@ -0,0 +1,50 @@ +/* + * ChannelWrongKeyError.java + * + * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * See: http://www.fsf.org/copyleft/lesser.txt + */ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 475 ERR_BADCHANNELKEY + * <channel> :Cannot join channel (+k) + * @author Morgan Christiansson + * @version $Id: ChannelWrongKeyError.java 85 2007-08-02 18:26:59Z jadestorm $ + * TODO: Should we rename to BadChannelKeyError to match others? + */ +public class ChannelWrongKeyError extends GenericJoinError +{ + public ChannelWrongKeyError() + { + super(); + } + + protected ChannelWrongKeyError(String chan, String comment) + { + super(chan, comment); + } + + public String getIrcIdentifier() + { + return "475"; + } + + protected InCommand create(String channel, String comment) { + return new ChannelWrongKeyError(channel, comment); + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ErroneusNicknameError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ErroneusNicknameError.java new file mode 100644 index 000000000..4b0bb6bbe --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ErroneusNicknameError.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Code: 432 ERR_ERRONEUSNICKNAME + * <nick> :Erroneus nickname + * Returned after receiving a NICK message which contains characters which do not fall in the defined set. + */ +public class ErroneusNicknameError extends GenericError +{ + private FullNick nick; + private String errorMessage; + + public ErroneusNicknameError() + { + } + + public ErroneusNicknameError(FullNick nick, String errorMessage) + { + this.nick = nick; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "432"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new ErroneusNicknameError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); + } + + public FullNick getNick() + { + return nick; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/FileErrorError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/FileErrorError.java new file mode 100644 index 000000000..a41205c7f --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/FileErrorError.java @@ -0,0 +1,39 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 424 ERR_FILEERROR + * :File error doing <file op> on <file> + * Generic error message used to report a failed file operation during the processing of a message. + */ +public class FileErrorError extends GenericError +{ + private String errorMessage; + + public FileErrorError() + { + } + + public FileErrorError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "424"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new FileErrorError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericError.java new file mode 100644 index 000000000..5e89fbfd0 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericError.java @@ -0,0 +1,14 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.commands.AbstractInCommand; + +/** + * Defines what an error is. All errors are commands. + */ +public abstract class GenericError extends AbstractInCommand +{ + +} + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericJoinError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericJoinError.java new file mode 100644 index 000000000..dfabcd3ef --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericJoinError.java @@ -0,0 +1,67 @@ +/* + * GenericJoinError.java + * + * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * See: http://www.fsf.org/copyleft/lesser.txt + */ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.util.ParameterIterator; + +/** + * @author Morgan Christiansson + * @version $Id: GenericJoinError.java 31 2004-04-01 22:02:33Z bdamm $ + */ +public abstract class GenericJoinError extends GenericError { + private String channel; + private String comment; + + public GenericJoinError() { + } + + protected GenericJoinError(String chan, String comment) + { + this.channel = chan; + this.comment = comment; + } + + protected abstract InCommand create(String channel, String comment); + + public String getChannel() + { + return channel; + } + + public String getComment() + { + return comment; + } + + public State getState() { + return State.UNKNOWN; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + ParameterIterator pI = new ParameterIterator( params ); + + pI.next(); // We know what our name is. + String channel = (String)pI.next(); + String comment = (String)pI.next(); + + return create( channel, comment ); + } +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/KeySetError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/KeySetError.java new file mode 100644 index 000000000..0d938263b --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/KeySetError.java @@ -0,0 +1,45 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 467 ERR_KEYSEY + * <channel> :Channel key already set + */ +public class KeySetError extends GenericError +{ + private String channel; + private String errorMessage; + + public KeySetError() + { + } + + public KeySetError(String channel, String errorMessage) + { + this.channel = channel; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "467"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new KeySetError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getChannel() + { + return channel; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/LoadTooHighError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/LoadTooHighError.java new file mode 100644 index 000000000..d6d4411b0 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/LoadTooHighError.java @@ -0,0 +1,49 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; + +public class LoadTooHighError extends GenericError +{ + private FullNick nick; + private String command; + private String errorMessage; + + public LoadTooHighError() + { + } + + public LoadTooHighError(FullNick nick, String command, String errorMessage) + { + this.nick = nick; + this.command = command; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "263"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new LoadTooHighError(new FullNick(getParameter(params, 1)), getParameter(params, 2), getParameter(params, 3)); + } + + public FullNick getNick() + { + return nick; + } + + public String getCommand() + { + return command; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NeedMoreParamsError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NeedMoreParamsError.java new file mode 100644 index 000000000..fa80c4dd6 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NeedMoreParamsError.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 461 ERR_NEEDMOREPARAMS + * <command> :Not enough parameters + * Returned by the server by numerous commands to indicate to the client that it didn't + * supply enough parameters. + */ +public class NeedMoreParamsError extends GenericError +{ + private String command; + private String errorMessage; + + public NeedMoreParamsError() + { + } + + public NeedMoreParamsError(String command, String errorMessage) + { + this.command = command; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "461"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NeedMoreParamsError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getCommand() + { + return command; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickCollisionError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickCollisionError.java new file mode 100644 index 000000000..bf098196c --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickCollisionError.java @@ -0,0 +1,48 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Code: 436 ERR_NICKCOLLISION + * <nick> :Nickname collision KILL + * Returned by a server to a client when it detects a nickname collision (registered of a NICK that + * already exists by another server). + */ +public class NickCollisionError extends GenericError +{ + private FullNick nick; + private String errorMessage; + + public NickCollisionError() + { + } + + public NickCollisionError(FullNick nick, String errorMessage) + { + this.nick = nick; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "436"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NickCollisionError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); + } + + public FullNick getNick() + { + return nick; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickInUseError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickInUseError.java new file mode 100644 index 000000000..93e37b4a4 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickInUseError.java @@ -0,0 +1,63 @@ +/* + * Original version: Ben Damm + * Changes by: Mog + * - Retains the nick that is in use + * */ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Code: 433 ERR_ERRONEUSNICKNAME + * <nick> :Nickname is already in use + * Returned when a NICK message is processed that result in an attempt to change + * to a currently existing nickname. + * TODO: Should we rename this to NicknameInUseError for consistency with rest of errors/matching RFC? + */ +public class NickInUseError extends GenericError +{ + private FullNick _nick; + String errorMessage; + + public NickInUseError() + { + _nick = null; + } + public NickInUseError(FullNick nick, String errorMessage) + { + _nick = nick; + this.errorMessage = errorMessage; + } + + public State getState() + { + return State.UNKNOWN; + } + + public String getIrcIdentifier() + { + return "433"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NickInUseError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); + } + + /** + * @return The nick in use. + */ + public FullNick getNick() + { + return _nick; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoAdminInfoError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoAdminInfoError.java new file mode 100644 index 000000000..10b14938b --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoAdminInfoError.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 423 ERR_NOADMININFO + * <server name> :No administrative info available + * Returned by a server in response to an ADMIN message when there is an error in finding the + * appropriate information. + */ +public class NoAdminInfoError extends GenericError +{ + private String server; + private String errorMessage; + + public NoAdminInfoError() + { + } + + public NoAdminInfoError(String server, String errorMessage) + { + this.server = server; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "423"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoAdminInfoError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getServer() + { + return server; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoLoginError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoLoginError.java new file mode 100644 index 000000000..12b2e39f3 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoLoginError.java @@ -0,0 +1,48 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Code: 444 ERR_NOLOGIN + * <user> :User not logged in + * Returned by the summon after a SUMMON command for a user was unable to be performed + * since they were not logged in. + */ +public class NoLoginError extends GenericError +{ + private FullNick nick; + private String errorMessage; + + public NoLoginError() + { + } + + public NoLoginError(FullNick nick, String errorMessage) + { + this.nick = nick; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "444"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoLoginError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); + } + + public FullNick getNick() + { + return nick; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoMotdError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoMotdError.java new file mode 100644 index 000000000..0f157a33f --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoMotdError.java @@ -0,0 +1,39 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 422 ERR_NOMOTD + * :MOTD File is missing + * Server's MOTD file could not be opened by the server. + */ +public class NoMotdError extends GenericError +{ + private String errorMessage; + + public NoMotdError() + { + } + + public NoMotdError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "422"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoMotdError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoNicknameGivenError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoNicknameGivenError.java new file mode 100644 index 000000000..7e2502d88 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoNicknameGivenError.java @@ -0,0 +1,39 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 431 ERR_NONICKNAMEGIVEN + * :No nickname given + * Returned when a nickname parameter expected for a command and isn't found. + */ +public class NoNicknameGivenError extends GenericError +{ + private String errorMessage; + + public NoNicknameGivenError() + { + } + + public NoNicknameGivenError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "431"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoNicknameGivenError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOperHostError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOperHostError.java new file mode 100644 index 000000000..5ab026987 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOperHostError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 491 ERR_NOOPERHOST + * :No O-lines for your host + * If a client sends an OPER message and the server has not been configured to allow + * connections from the client's host as an operator, this error must be returned. + */ +public class NoOperHostError extends GenericError +{ + private String errorMessage; + + public NoOperHostError() + { + } + + public NoOperHostError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "491"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoOperHostError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOriginError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOriginError.java new file mode 100644 index 000000000..3ed8542fb --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOriginError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 409 ERR_NOORIGIN + * :No origin specified + * PING or PONG message missing the originator parameter which is required since these commands must + * work without valid prefixes. + */ +public class NoOriginError extends GenericError +{ + private String errorMessage; + + public NoOriginError() + { + } + + public NoOriginError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "409"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoOriginError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPermForHostError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPermForHostError.java new file mode 100644 index 000000000..2cf22c211 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPermForHostError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 463 ERR_NOPERMFORHOST + * :Your host isn't among the privileged + * Returned to a client which attempts to register with a server which does not been setup to allow + * connections from the host the attempted connection is tried. + */ +public class NoPermForHostError extends GenericError +{ + private String errorMessage; + + public NoPermForHostError() + { + } + + public NoPermForHostError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "463"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoPermForHostError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPrivilegesError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPrivilegesError.java new file mode 100644 index 000000000..d94df8172 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPrivilegesError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 481 ERR_NOPRIVILEGES + * :Permission Denied- You're not an IRC operator + * Any command requiring operator privileges to operate must return this error to + * indicate the attempt was unsuccessful. + */ +public class NoPrivilegesError extends GenericError +{ + private String errorMessage; + + public NoPrivilegesError() + { + } + + public NoPrivilegesError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "481"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoPrivilegesError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoRecipientError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoRecipientError.java new file mode 100644 index 000000000..e86cefc6c --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoRecipientError.java @@ -0,0 +1,38 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 411 ERR_NORECIPIENT + * :No recipient given (<command>) + */ +public class NoRecipientError extends GenericError +{ + private String errorMessage; + + public NoRecipientError() + { + } + + public NoRecipientError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "411"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoRecipientError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchChannelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchChannelError.java new file mode 100644 index 000000000..bf8b3910d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchChannelError.java @@ -0,0 +1,46 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 403 ERR_NOSUCHCHANNEL + * <channel name> :No such channel + * Used to indicate the given channel name is invalid. + */ +public class NoSuchChannelError extends GenericError +{ + private String channel; + private String errorMessage; + + public NoSuchChannelError() + { + } + + public NoSuchChannelError(String channel, String errorMessage) + { + this.channel = channel; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "403"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoSuchChannelError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getChannel() + { + return channel; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchNickError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchNickError.java new file mode 100644 index 000000000..664a2c9d0 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchNickError.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Code: 401 ERR_NOSUCHNICK + * <nickname> :No such nick/channel + * Used to indicated the nickname parameter supplied to a command is currently unused. + */ +public class NoSuchNickError extends GenericError +{ + private FullNick nick; + private String errorMessage; + + public NoSuchNickError() + { + } + + public NoSuchNickError(FullNick nick, String errorMessage) + { + this.nick = nick; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "401"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoSuchNickError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); + } + + public FullNick getNick() + { + return nick; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchServerError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchServerError.java new file mode 100644 index 000000000..cdb0dee90 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchServerError.java @@ -0,0 +1,46 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 402 ERR_NOSUCHSERVER + * <server name> :No such server + * Used to indicate the server name given currently doesn't exist. + */ +public class NoSuchServerError extends GenericError +{ + private String server; + private String errorMessage; + + public NoSuchServerError() + { + } + + public NoSuchServerError(String server, String errorMessage) + { + this.server = server; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "402"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoSuchServerError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getServer() + { + return server; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTextToSendError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTextToSendError.java new file mode 100644 index 000000000..6e0176295 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTextToSendError.java @@ -0,0 +1,41 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 412 ERR_NOTEXTTOSEND + * :No text to send + * 412 - 414 are returned by PRIVMSG to indicate that the message wasn't delivered for some reason. + * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that are returned when an invalid use of + * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. + */ +public class NoTextToSendError extends GenericError +{ + private String errorMessage; + + public NoTextToSendError() + { + } + + public NoTextToSendError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "412"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoTextToSendError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTopLevelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTopLevelError.java new file mode 100644 index 000000000..4810ab8a1 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTopLevelError.java @@ -0,0 +1,48 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 413 ERR_NOTOPLEVEL + * <mask> :No toplevel domain specified + * 412 - 414 are returned by PRIVMSG to indicate that the message wasn't delivered for some reason. + * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that are returned when an invalid use of + * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. + */ +public class NoTopLevelError extends GenericError +{ + private String mask; + private String errorMessage; + + public NoTopLevelError() + { + } + + public NoTopLevelError(String mask, String errorMessage) + { + this.mask = mask; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "413"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NoTopLevelError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getMask() + { + return mask; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotOnChannelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotOnChannelError.java new file mode 100644 index 000000000..8c1346012 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotOnChannelError.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 442 ERR_NOTONCHANNEL + * <channel> :You're not on that channel + * Returned by the server whenever a client tries to perform a channel effecting command for which the + * client isn't a member. + */ +public class NotOnChannelError extends GenericError +{ + private String channel; + private String errorMessage; + + public NotOnChannelError() + { + } + + public NotOnChannelError(String channel, String errorMessage) + { + this.channel = channel; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "442"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NotOnChannelError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getChannel() + { + return channel; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotRegisteredError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotRegisteredError.java new file mode 100644 index 000000000..f443901d1 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotRegisteredError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 451 ERR_NOTREGISTERED + * :You have not registered + * Returned by the server to indicate that the client must be registered before the + * server will allow it to be parsed in detail. + */ +public class NotRegisteredError extends GenericError +{ + private String errorMessage; + + public NotRegisteredError() + { + } + + public NotRegisteredError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "451"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NotRegisteredError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/PasswdMismatchError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/PasswdMismatchError.java new file mode 100644 index 000000000..b775b16c4 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/PasswdMismatchError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 464 ERR_PASSWDMISMATCH + * :Password incorrect + * Returned to indicate a failed attempt at registering a connection for which a + * password was required and was either not given or incorrect. + */ +public class PasswdMismatchError extends GenericError +{ + private String errorMessage; + + public PasswdMismatchError() + { + } + + public PasswdMismatchError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "464"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new PasswdMismatchError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/SummonDisabledError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/SummonDisabledError.java new file mode 100644 index 000000000..0f495fcf4 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/SummonDisabledError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 445 ERR_SUMMONDISABLED + * :SUMMON has been disabled + * Returned as a response to the SUMMON command. Must be returned by any server + * which does not implement it. + */ +public class SummonDisabledError extends GenericError +{ + private String errorMessage; + + public SummonDisabledError() + { + } + + public SummonDisabledError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "445"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new SummonDisabledError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyChannelsError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyChannelsError.java new file mode 100644 index 000000000..a18d92b20 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyChannelsError.java @@ -0,0 +1,46 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 405 ERR_TOOMANYCHANNELS + * <channel name> :You have joined too many channels + * Sent to a user when they have joined the maximum number of allowed channels and they try to join another channel. + */ +public class TooManyChannelsError extends GenericError +{ + private String channel; + private String errorMessage; + + public TooManyChannelsError() + { + } + + public TooManyChannelsError(String channel, String errorMessage) + { + this.channel = channel; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "405"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new TooManyChannelsError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getChannel() + { + return channel; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyTargetsError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyTargetsError.java new file mode 100644 index 000000000..594fe4e41 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyTargetsError.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 407 ERR_TOOMANYTARGETS + * <target> :Duplicate recipients. No message delivered + * Returned to a client which is attempting to send a PRIVMSG/NOTICE using the user@host destination + * format and for a user@host which has several occurrences. + */ +public class TooManyTargetsError extends GenericError +{ + private String dest; + private String errorMessage; + + public TooManyTargetsError() + { + } + + public TooManyTargetsError(String dest, String errorMessage) + { + this.dest = dest; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "407"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new TooManyTargetsError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getDest() + { + return dest; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UModeUnknownFlagError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UModeUnknownFlagError.java new file mode 100644 index 000000000..9f112e256 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UModeUnknownFlagError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 501 ERR_UMODEUNKNOWNFLAG + * :Unknown MODE flag + * Returned by the server to indicate that a MODE message was sent with a nickname + * parameter and that the a mode flag sent was not recognized. + */ +public class UModeUnknownFlagError extends GenericError +{ + private String errorMessage; + + public UModeUnknownFlagError() + { + } + + public UModeUnknownFlagError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "501"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new UModeUnknownFlagError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownCommandError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownCommandError.java new file mode 100644 index 000000000..6fd01f0ad --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownCommandError.java @@ -0,0 +1,46 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 421 ERR_UNKNOWNCOMMAND + * <command> :Unknown command + * Returned to a registered client to indicate that the command sent is unknown by the server. + */ +public class UnknownCommandError extends GenericError +{ + private String command; + private String errorMessage; + + public UnknownCommandError() + { + } + + public UnknownCommandError(String command, String errorMessage) + { + this.command = command; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "421"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new UnknownCommandError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getCommand() + { + return command; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownError.java new file mode 100644 index 000000000..225361294 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownError.java @@ -0,0 +1,69 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.commands.UnknownCommand; + + +/** + * Some unknown command, for which there is no factory. This is a + * special case command, created by IRCConnection if it can't find a + * proper command object. + */ +public class UnknownError extends UnknownCommand +{ + + private String errorStr; + private int errorCode; + + public UnknownError( String ident ) + { + errorStr = ident; + errorCode = Integer.parseInt( ident ); + } + + public int getErrorCode() + { + return errorCode; + } + + public String getError() + { + return errorStr; + } + + public static boolean isError( String ident ) + { + char c = ident.charAt(0); + return ( c == '4' || c == '5' ); + } + + public State getState() + { + return State.UNKNOWN; + } + + /** + * Never parsed. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + throw new UnsupportedOperationException("UnknownError does no parsing."); + } + + /** + * Unknown, so we don't know what the identifier is ahead of time. + */ + public String getIrcIdentifier() + { + return errorStr; + } + + public String toString() + { + return "UnknownError[" + errorStr + "]"; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownModeError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownModeError.java new file mode 100644 index 000000000..ebd10358d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownModeError.java @@ -0,0 +1,45 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 472 ERR_UNKNOWNMODE + * <char> :is unknown mode char to me + */ +public class UnknownModeError extends GenericError +{ + private Character mode; + private String errorMessage; + + public UnknownModeError() + { + } + + public UnknownModeError(Character mode, String errorMessage) + { + this.mode = mode; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "472"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new UnknownModeError(getParameter(params, 1).charAt(0), getParameter(params, 2)); + } + + public Character getMode() + { + return mode; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserNotInChannelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserNotInChannelError.java new file mode 100644 index 000000000..b1734818f --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserNotInChannelError.java @@ -0,0 +1,54 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Code: 441 ERR_USERNOTINCHANNEL + * <user> <channel> :They aren't on that channel + * Returned by the server to indicate that the target user of the command is not on the given channel. + */ +public class UserNotInChannelError extends GenericError +{ + private FullNick nick; + private String channel; + private String errorMessage; + + public UserNotInChannelError() + { + } + + public UserNotInChannelError(FullNick nick, String channel, String errorMessage) + { + this.nick = nick; + this.channel = channel; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "441"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new UserNotInChannelError(new FullNick(getParameter(params, 1)), getParameter(params, 2), getParameter(params, 3)); + } + + public FullNick getNick() + { + return nick; + } + + public String getChannel() + { + return channel; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserOnChannelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserOnChannelError.java new file mode 100644 index 000000000..6d5b53bd2 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserOnChannelError.java @@ -0,0 +1,54 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Code: 443 ERR_USERONCHANNEL + * <user> <channel> :is already on channel + * Returned when a client tries to invite a user to a channel they are already on. + */ +public class UserOnChannelError extends GenericError +{ + private FullNick nick; + private String channel; + private String errorMessage; + + public UserOnChannelError() + { + } + + public UserOnChannelError(FullNick nick, String channel, String errorMessage) + { + this.nick = nick; + this.channel = channel; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "443"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new UserOnChannelError(new FullNick(getParameter(params, 1)), getParameter(params, 2), getParameter(params, 3)); + } + + public FullNick getNick() + { + return nick; + } + + public String getChannel() + { + return channel; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDisabledError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDisabledError.java new file mode 100644 index 000000000..b09c0f929 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDisabledError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 446 ERR_USERSDISABLED + * :USERS has been disabled + * Returned as a response to the USERS command. Must be returned by any server which + * does not implement it. + */ +public class UsersDisabledError extends GenericError +{ + private String errorMessage; + + public UsersDisabledError() + { + } + + public UsersDisabledError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "446"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new UsersDisabledError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDontMatchError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDontMatchError.java new file mode 100644 index 000000000..e8fe565e4 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDontMatchError.java @@ -0,0 +1,39 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 502 ERR_USERSDONTMATCH + * :Cant change mode for other users + * Error sent to any user trying to view or change the user mode for a user other than themselves. + */ +public class UsersDontMatchError extends GenericError +{ + private String errorMessage; + + public UsersDontMatchError() + { + } + + public UsersDontMatchError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "502"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new UsersDontMatchError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WasNoSuchNickError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WasNoSuchNickError.java new file mode 100644 index 000000000..82c0545d7 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WasNoSuchNickError.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.FullNick; + +/** + * Code: 406 ERR_WASNOSUCHNICK + * <nickname> :There was no such nickname + * Returned by WHOWAS to indicate there is no history information for that nickname. + */ +public class WasNoSuchNickError extends GenericError +{ + private FullNick nick; + private String errorMessage; + + public WasNoSuchNickError() + { + } + + public WasNoSuchNickError(FullNick nick, String errorMessage) + { + this.nick = nick; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "406"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new WasNoSuchNickError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); + } + + public FullNick getNick() + { + return nick; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WildTopLevelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WildTopLevelError.java new file mode 100644 index 000000000..2fb641f24 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WildTopLevelError.java @@ -0,0 +1,48 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 414 ERR_WILDTOPLEVEL + * <mask> :Wildcard in toplevel domain + * 412 - 414 are returned by PRIVMSG to indicate that the message wasn't delivered for some reason. + * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that are returned when an invalid use of + * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. + */ +public class WildTopLevelError extends GenericError +{ + private String mask; + private String errorMessage; + + public WildTopLevelError() + { + } + + public WildTopLevelError(String mask, String errorMessage) + { + this.mask = mask; + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "414"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new WildTopLevelError(getParameter(params, 1), getParameter(params, 2)); + } + + public String getMask() + { + return mask; + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/YoureBannedCreepError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/YoureBannedCreepError.java new file mode 100644 index 000000000..1cea503dc --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/YoureBannedCreepError.java @@ -0,0 +1,40 @@ +package f00f.net.irc.martyr.errors; + +import f00f.net.irc.martyr.InCommand; + +/** + * Code: 465 ERR_YOUREBANNEDCREEP + * :You are banned from this server + * Returned after an attempt to connect and register yourself with a server which has been setup to + * explicitly deny connections to you. + */ +public class YoureBannedCreepError extends GenericError +{ + private String errorMessage; + + public YoureBannedCreepError() + { + } + + public YoureBannedCreepError(String errorMessage) + { + this.errorMessage = errorMessage; + } + + public String getIrcIdentifier() + { + return "465"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new YoureBannedCreepError(getParameter(params, 1)); + } + + public String getErrorMessage() + { + return errorMessage; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/GenericMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/GenericMode.java new file mode 100644 index 000000000..e1dad6045 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/GenericMode.java @@ -0,0 +1,77 @@ +package f00f.net.irc.martyr.modes; + +import f00f.net.irc.martyr.Mode; + +/** + * GenericNode uses the character to specify the hash code. Thus, two + * mode types are the same, in a hash table, even if they have + * different parameters or positive/negative values. + */ +public abstract class GenericMode implements Mode +{ + private String str; + private Mode.Sign sign = Mode.Sign.NOSIGN; + + public void setParam( String str ) + { + this.str = str; + } + + public String getParam() + { + return str; + } + + public void setSign( Mode.Sign sign ) + { + this.sign = sign; + } + + public Mode.Sign getSign() + { + return sign; + } + + public String toString() + { + String pString = " "; + if( sign != Mode.Sign.NOSIGN ) + pString += ( sign == Mode.Sign.POSITIVE ? "+" : "-" ); + String className = this.getClass().getName(); + className = className.substring( className.indexOf('$')+1 ); + + String result = className + pString + getChar(); + if( requiresParam() ) + { + result += " " + getParam(); + } + + return result; + } + + public boolean equals( Object o ) + { + if( o instanceof Mode ) + { + Mode oMode = (Mode)o; + + if( oMode.getParam() == null || this.getParam() == null ) + return oMode.getChar() == this.getChar(); + + if( oMode.getParam() == null && this.getParam() != null ) + return false; + if( oMode.getParam() == null && this.getParam() == null ) + return oMode.getChar() == this.getChar(); + + return oMode.getChar() == this.getChar() && + oMode.getParam().equals(this.getParam()); + } + return false; + } + + public int hashCode() + { + return (int)getChar(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/README b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/README new file mode 100644 index 000000000..8d2e25c18 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/README @@ -0,0 +1,8 @@ +This directory contains modes. Unlike commands, errors, and replies, +these modes do NOT contain any information about the mode other than +what it is. The Mode objects know if the mode takes a parameter, what +character represents the mode, and contain a method to create a new +instance of itself. + +You can get and set parameters using the Mode related commands. + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/AnonChannelMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/AnonChannelMode.java new file mode 100644 index 000000000..9fd215416 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/AnonChannelMode.java @@ -0,0 +1,44 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

The channel flag 'a' defines an anonymous channel. This means that + * when a message sent to the channel is sent by the server to users, + * and the origin is a user, then it MUST be masked. To mask the + * message, the origin is changed to "anonymous!anonymous@anonymous." + * (e.g., a user with the nickname "anonymous", the username "anonymous" + * and from a host called "anonymous."). Because of this, servers MUST + * forbid users from using the nickname "anonymous". Servers MUST also + * NOT send QUIT messages for users leaving such channels to the other + * channel members but generate a PART message instead.

+ * + *

On channels with the character '&' as prefix, this flag MAY be + * toggled by channel operators, but on channels with the character '!' + * as prefix, this flag can be set (but SHALL NOT be unset) by the + * "channel creator" only. This flag MUST NOT be made available on + * other types of channels.

+ * + *

Replies to the WHOIS, WHO and NAMES commands MUST NOT reveal the + * presence of other users on channels for which the anonymous flag is + * set.

+ * (From RFC2811) + */ +public class AnonChannelMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return false; + } + + public char getChar() + { + return 'a'; + } + + public Mode newInstance() + { + return new AnonChannelMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/BanMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/BanMode.java new file mode 100644 index 000000000..d169370cb --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/BanMode.java @@ -0,0 +1,38 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Channel Ban and Exception - When a user requests to join a + * channel, his local server checks if the user's address matches + * any of the ban masks set for the channel. If a match is found, + * the user request is denied unless the address also matches an + * exception mask set for the channel.

+ * + *

Servers MUST NOT allow a channel member who is banned from the + * channel to speak on the channel, unless this member is a channel + * operator or has voice privilege. (See Section 4.1.3 (Voice + * Privilege)).

+ * + *

A user who is banned from a channel and who carries an invitation + * sent by a channel operator is allowed to join the channel.

+ * (From RFC2811) + */ +public class BanMode extends GenericChannelMask +{ + public boolean requiresParam() + { + return true; + } + + public char getChar() + { + return 'b'; + } + + public Mode newInstance() + { + return new BanMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ExceptionMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ExceptionMode.java new file mode 100644 index 000000000..63f3d03f8 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ExceptionMode.java @@ -0,0 +1,38 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Channel Ban and Exception - When a user requests to join a + * channel, his local server checks if the user's address matches + * any of the ban masks set for the channel. If a match is found, + * the user request is denied unless the address also matches an + * exception mask set for the channel.

+ * + *

Servers MUST NOT allow a channel member who is banned from the + * channel to speak on the channel, unless this member is a channel + * operator or has voice privilege. (See Section 4.1.3 (Voice + * Privilege)).

+ * + *

A user who is banned from a channel and who carries an invitation + * sent by a channel operator is allowed to join the channel.

+ * (From RFC2811) +*/ +public class ExceptionMode extends GenericChannelMask +{ + public boolean requiresParam() + { + return true; + } + + public char getChar() + { + return 'e'; + } + + public Mode newInstance() + { + return new ExceptionMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMask.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMask.java new file mode 100644 index 000000000..13e1fc3de --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMask.java @@ -0,0 +1,16 @@ +package f00f.net.irc.martyr.modes.channel; + + +/** + * 'Masks' and other modes that can have multiple copies in a channel + * at once should subclass this. + */ +public abstract class GenericChannelMask extends GenericChannelMode +{ + public boolean onePerChannel() + { + return false; + } +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMode.java new file mode 100644 index 000000000..d65f850b8 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMode.java @@ -0,0 +1,23 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.modes.GenericMode; + +/** + * A generic channel mode will be recorded in the channel, and there + * will be one per channel. Modes that can have multiple copies in + * the channel (masks) should subclass GenericChannelMask. + */ +public abstract class GenericChannelMode extends GenericMode +{ + public boolean recordInChannel() + { + return true; + } + + public boolean onePerChannel() + { + return true; + } +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteMaskMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteMaskMode.java new file mode 100644 index 000000000..c9faa27fc --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteMaskMode.java @@ -0,0 +1,30 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Channel Invitation - For channels which have the invite-only + * flag set (See Section 4.2.2 (Invite Only Flag)), users whose + * address matches an invitation mask set for the channel are + * allowed to join the channel without any + * invitation.

+ * (From RFC2811) + */ +public class InviteMaskMode extends GenericChannelMask +{ + public boolean requiresParam() + { + return true; + } + + public char getChar() + { + return 'I'; + } + + public Mode newInstance() + { + return new InviteMaskMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteOnlyMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteOnlyMode.java new file mode 100644 index 000000000..45da646c9 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteOnlyMode.java @@ -0,0 +1,32 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Invite Only Flag - When the channel flag 'i' is set, new + * members are only accepted if their mask matches Invite-list (See + * section 4.3.2) or they have been invited by a channel operator. + * This flag also restricts the usage of the INVITE command (See + * "IRC Client Protocol" [IRC-CLIENT]) to channel operators.

+ * (From RFC2811) + * + * @see InviteMaskMode + */ +public class InviteOnlyMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return false; + } + + public char getChar() + { + return 'i'; + } + + public Mode newInstance() + { + return new InviteOnlyMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/KeyMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/KeyMode.java new file mode 100644 index 000000000..9f29da431 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/KeyMode.java @@ -0,0 +1,31 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Channel Key - When a channel key is set (by using the mode + * 'k'), servers MUST reject their local users request to join the + * channel unless this key is given.

+ * + *

The channel key MUST only be made visible to the channel members in + * the reply sent by the server to a MODE query.

+ * (From RFC2811) + */ +public class KeyMode extends GenericChannelMask +{ + public boolean requiresParam() + { + return true; + } + + public char getChar() + { + return 'k'; + } + + public Mode newInstance() + { + return new KeyMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/LimitMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/LimitMode.java new file mode 100644 index 000000000..028739705 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/LimitMode.java @@ -0,0 +1,31 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

User Limit - A user limit may be set on channels by using the + * channel flag 'l'. When the limit is reached, servers MUST + * forbid their local users to join the channel.

+ * + *

The value of the limit MUST only be made available to the channel + * members in the reply sent by the server to a MODE query.

+ * (From RFC2811) +*/ +public class LimitMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return true; + } + + public char getChar() + { + return 'l'; + } + + public Mode newInstance() + { + return new LimitMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ModeratedMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ModeratedMode.java new file mode 100644 index 000000000..d0938a565 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ModeratedMode.java @@ -0,0 +1,31 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Moderated Channel Flag - The channel flag 'm' is used to + * control who may speak on a channel. When it is set, only + * channel operators, and members who have been given the voice + * privilege may send messages to the channel.

+ * + *

This flag only affects users.

+ * (From RFC2811) + */ +public class ModeratedMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return false; + } + + public char getChar() + { + return 'm'; + } + + public Mode newInstance() + { + return new ModeratedMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/NoExtMsgMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/NoExtMsgMode.java new file mode 100644 index 000000000..029baf760 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/NoExtMsgMode.java @@ -0,0 +1,30 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

No Messages To Channel From Clients On The Outside - When the + * channel flag 'n' is set, only channel members MAY send messages + * to the channel.

+ * + *

This flag only affects users.

+ * (From RFC2811) + */ +public class NoExtMsgMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return false; + } + + public char getChar() + { + return 'n'; + } + + public Mode newInstance() + { + return new NoExtMsgMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/OperMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/OperMode.java new file mode 100644 index 000000000..e8f45f0be --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/OperMode.java @@ -0,0 +1,31 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Channel Operator Status - The mode 'o' is used to toggle the + * operator status of a channel member.

(From RFC2811) + * + *

Note that OperMode is recorded in the channel, but checking the op + * status of a member will give you a true list of who is and isn't an + * operator. This is because we don't know the entire list of modes + * when entering a channel.

+ */ +public class OperMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return true; + } + + public char getChar() + { + return 'o'; + } + + public Mode newInstance() + { + return new OperMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/PrivateMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/PrivateMode.java new file mode 100644 index 000000000..580b957e6 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/PrivateMode.java @@ -0,0 +1,50 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Private and Secret Channels - The channel flag 'p' is used to + * mark a channel "private" and the channel flag 's' to mark a + * channel "secret". Both properties are similar and conceal the + * existence of the channel from other users.

+ * + *

This means that there is no way of getting this channel's name from + * the server without being a member. In other words, these channels + * MUST be omitted from replies to queries like the WHOIS + * command.

+ * + *

When a channel is "secret", in addition to the restriction above, the + * server will act as if the channel does not exist for queries like the + * TOPIC, LIST, NAMES commands. Note that there is one exception to + * this rule: servers will correctly reply to the MODE command. + * Finally, secret channels are not accounted for in the reply to the + * LUSERS command (See "Internet Relay Chat: Client Protocol" [IRC- + * CLIENT]) when the <mask> parameter is specified.

+ * + *

The channel flags 'p' and 's' MUST NOT both be set at the same time. + * If a MODE message originating from a server sets the flag 'p' and the + * flag 's' is already set for the channel, the change is silently + * ignored. This should only happen during a split healing phase + * (mentioned in the "IRC Server Protocol" document + * [IRC-SERVER]).

+ * + * (From RFC2811) + */ +public class PrivateMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return false; + } + + public char getChar() + { + return 'p'; + } + + public Mode newInstance() + { + return new PrivateMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/SecretMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/SecretMode.java new file mode 100644 index 000000000..33bb13733 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/SecretMode.java @@ -0,0 +1,50 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Private and Secret Channels - The channel flag 'p' is used to + * mark a channel "private" and the channel flag 's' to mark a + * channel "secret". Both properties are similar and conceal the + * existence of the channel from other users.

+ * + *

This means that there is no way of getting this channel's name from + * the server without being a member. In other words, these channels + * MUST be omitted from replies to queries like the WHOIS + * command.

+ * + *

When a channel is "secret", in addition to the restriction above, the + * server will act as if the channel does not exist for queries like the + * TOPIC, LIST, NAMES commands. Note that there is one exception to + * this rule: servers will correctly reply to the MODE command. + * Finally, secret channels are not accounted for in the reply to the + * LUSERS command (See "Internet Relay Chat: Client Protocol" [IRC- + * CLIENT]) when the <mask> parameter is specified.

+ * + *

The channel flags 'p' and 's' MUST NOT both be set at the same time. + * If a MODE message originating from a server sets the flag 'p' and the + * flag 's' is already set for the channel, the change is silently + * ignored. This should only happen during a split healing phase + * (mentioned in the "IRC Server Protocol" document + * [IRC-SERVER]).

+ * + * (From RFC2811) + */ +public class SecretMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return false; + } + + public char getChar() + { + return 's'; + } + + public Mode newInstance() + { + return new SecretMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/TopicLockMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/TopicLockMode.java new file mode 100644 index 000000000..c6f9b8a81 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/TopicLockMode.java @@ -0,0 +1,27 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Topic - The channel flag 't' is used to restrict the usage of the TOPIC + * command to channel operators.

+ * (From RFC2811) + */ +public class TopicLockMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return false; + } + + public char getChar() + { + return 't'; + } + + public Mode newInstance() + { + return new TopicLockMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/VoiceMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/VoiceMode.java new file mode 100644 index 000000000..8d5faeac3 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/VoiceMode.java @@ -0,0 +1,34 @@ +package f00f.net.irc.martyr.modes.channel; + +import f00f.net.irc.martyr.Mode; + +/** + *

Voice Privilege - The mode 'v' is used to give and take voice + * privilege to/from a channel member. Users with this privilege + * can talk on moderated channels. (See section 4.2.3 (Moderated + * Channel Flag).

+ * (From RFC2811) + */ +public class VoiceMode extends GenericChannelMode +{ + public boolean requiresParam() + { + return true; + } + + public char getChar() + { + return 'v'; + } + + public boolean recordInChannel() + { + return false; + } + + public Mode newInstance() + { + return new VoiceMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/GenericUserMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/GenericUserMode.java new file mode 100644 index 000000000..7a3767d2d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/GenericUserMode.java @@ -0,0 +1,24 @@ +package f00f.net.irc.martyr.modes.user; + +import f00f.net.irc.martyr.modes.GenericMode; + +/** + * + */ +public abstract class GenericUserMode extends GenericMode +{ + public boolean recordInChannel() + { + return false; + } + + /** + * Well, this is kind of irrelevent isn't it? + */ + public boolean onePerChannel() + { + return false; + } +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/InvisibleMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/InvisibleMode.java new file mode 100644 index 000000000..f86da15a5 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/InvisibleMode.java @@ -0,0 +1,22 @@ +package f00f.net.irc.martyr.modes.user; + +import f00f.net.irc.martyr.Mode; + +public class InvisibleMode extends GenericUserMode +{ + public char getChar() + { + return 'i'; + } + + public boolean requiresParam() + { + return false; + } + + public Mode newInstance() + { + return new InvisibleMode(); + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AbstractWhoisReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AbstractWhoisReply.java new file mode 100644 index 000000000..d52e59dcf --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AbstractWhoisReply.java @@ -0,0 +1,58 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.util.ParameterIterator; + +public abstract class AbstractWhoisReply extends GenericReply +{ + //static Logger log = Logger.getLogger(AbstractWhoisReply.class); + + private String target = null; + + /** + * Factory constructor. + * */ + public AbstractWhoisReply() + { + } + + public AbstractWhoisReply( String params ) + { + ParameterIterator pi = getParams( params ); + parseParams( pi ); + } + + public abstract String getIrcIdentifier(); + + /** + * Parse the parameters, but the target param has already been + * stripped off. + * + * @param pi Parameter iterator that will parse the parameters + * */ + protected abstract void parseParams( ParameterIterator pi ); + + /** + * @return the target of the whois + * */ + public String getTarget() + { + return target; + } + + /** + * @param params the params string passed to "parse". + * @return a parameter iterator, with the whois target already + * stripped off. + * */ + protected ParameterIterator getParams( String params ) + { + ParameterIterator pi = new ParameterIterator(params); + pi.next(); // throw away our own nick + this.target = (String)pi.next(); + //log.debug("AbstractWhoisReply: Whois target: " + target); + + return pi; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AwayReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AwayReply.java new file mode 100644 index 000000000..a7105546e --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AwayReply.java @@ -0,0 +1,49 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +/** + * Signals an automated AWAY message received as a response to a PRIVMSG that was sent out. + * + * @author Daniel Henninger + */ +public class AwayReply extends GenericReply +{ + + private String nick; + private String message; + + /** + * Factory constructor. + */ + public AwayReply() + { + } + + public AwayReply(String nick, String message) + { + this.nick = nick; + this.message = message; + } + + public String getIrcIdentifier() + { + return "301"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new AwayReply(getParameter(params, 1), getParameter(params, 2)); + } + + public String getNick() + { + return nick; + } + + public String getMessage() + { + return message; + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ChannelCreationReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ChannelCreationReply.java new file mode 100644 index 000000000..2dd89e1cd --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ChannelCreationReply.java @@ -0,0 +1,78 @@ +package f00f.net.irc.martyr.replies; + +import java.util.Date; +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; + +/** + * ChannelCreationReply sets the creation time of the channel. It is sent + * automatically on a MODE discovery request. + */ +public class ChannelCreationReply extends GenericReply +{ + private String channelName; + private Date date; + + /** For use as a factory. */ + public ChannelCreationReply() + { + } + + public ChannelCreationReply( String channelName, Date date ) + { + this.channelName = channelName; + this.date = date; + } + + public String getIrcIdentifier() + { + return "329"; + } + + /** + * This is a factory that passes the command off to a + * ChannelModeCommand. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + StringTokenizer tokens = new StringTokenizer( params ); + + // Our nick. We don't need that, I think. + tokens.nextToken(); + + // The channel. + String chan = tokens.nextToken(); + + // The date. + Date date; + try + { + date = new Date( Long.parseLong( tokens.nextToken() ) * 1000 ); + } + catch( NumberFormatException nfe ) + { + // riiiight... + date = new Date(0); + } + + return new ChannelCreationReply( chan, date ); + } + + /** + * This should, theoretically, never be called, because this command is + * only ever used as a factory. + */ + public boolean updateClientState( ClientState state ) + { + Channel channel = state.getChannel( channelName ); + channel.setCreationDate( date ); + return true; + } +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericReply.java new file mode 100644 index 000000000..eabdf2658 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericReply.java @@ -0,0 +1,16 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.commands.AbstractInCommand; + +/** + * Defines what a reply is. A reply is really the same as an error, + * it just doesn't signify an error. + */ +public abstract class GenericReply extends AbstractInCommand +{ + + +} + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericStringReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericStringReply.java new file mode 100644 index 000000000..38d609ac6 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericStringReply.java @@ -0,0 +1,23 @@ +package f00f.net.irc.martyr.replies; + +public abstract class GenericStringReply extends GenericReply +{ + + private String string; + + public GenericStringReply() + { + } + + public GenericStringReply( String string ) + { + this.string = string; + } + + public String getString() + { + return string; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserClientReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserClientReply.java new file mode 100644 index 000000000..c108fe919 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserClientReply.java @@ -0,0 +1,28 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +public class LUserClientReply extends GenericStringReply +{ + + public LUserClientReply() + { + } + + public LUserClientReply( String string ) + { + super( string ); + } + + public String getIrcIdentifier() + { + return "251"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new LUserClientReply( getParameter( params, 1 ) ); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserMeReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserMeReply.java new file mode 100644 index 000000000..9083f0a73 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserMeReply.java @@ -0,0 +1,28 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +public class LUserMeReply extends GenericStringReply +{ + + public LUserMeReply() + { + } + + public LUserMeReply( String string ) + { + super( string ); + } + + public String getIrcIdentifier() + { + return "255"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new LUserMeReply( getParameter( params, 1 ) ); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserOpReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserOpReply.java new file mode 100644 index 000000000..b05efedc1 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserOpReply.java @@ -0,0 +1,36 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +public class LUserOpReply extends GenericStringReply +{ + + private int numOps; + + public LUserOpReply() + { + } + + public LUserOpReply( int ops, String string ) + { + super( string ); + this.numOps = ops; + } + + public String getIrcIdentifier() + { + return "252"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new LUserOpReply( getIntParameter( params, 1, -1 ), getParameter( params, 2 ) ); + } + + public int getNumOps() + { + return numOps; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListEndReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListEndReply.java new file mode 100644 index 000000000..6a0b1ca7f --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListEndReply.java @@ -0,0 +1,31 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +/** + * Signals the end of a LIST response. + * + * @author Daniel Henninger + */ +public class ListEndReply extends GenericReply +{ + + /** + * Factory constructor. + */ + public ListEndReply() + { + } + + public String getIrcIdentifier() + { + return "323"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new ListEndReply(); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListReply.java new file mode 100644 index 000000000..a814c5a43 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListReply.java @@ -0,0 +1,63 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +/** + * Signals an entry of a LIST response. + * + * @author Daniel Henninger + */ +public class ListReply extends GenericReply +{ + + private String requestor; + private String channel; + private Integer memberCount; + private String topic; + + /** + * Factory constructor. + */ + public ListReply() + { + } + + public ListReply(String requestor, String channel, Integer memberCount, String topic) + { + this.requestor = requestor; + this.channel = channel; + this.memberCount = memberCount; + this.topic = topic; + } + + public String getIrcIdentifier() + { + return "322"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new ListReply(getParameter(params, 0), getParameter(params, 1), Integer.parseInt(getParameter(params, 2)), getParameter(params, 3)); + } + + public String getChannel() + { + return channel; + } + + public Integer getMemberCount() + { + return memberCount; + } + + public String getTopic() + { + return topic; + } + + public String getRequestor() + { + return requestor; + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListStartReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListStartReply.java new file mode 100644 index 000000000..0f00d6c3f --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListStartReply.java @@ -0,0 +1,31 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +/** + * Signals the beginning of a LIST response. + * + * @author Daniel Henninger + */ +public class ListStartReply extends GenericReply +{ + + /** + * Factory constructor. + */ + public ListStartReply() + { + } + + public String getIrcIdentifier() + { + return "321"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new ListStartReply(); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ModeReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ModeReply.java new file mode 100644 index 000000000..d355e45e3 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ModeReply.java @@ -0,0 +1,54 @@ +package f00f.net.irc.martyr.replies; + +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.commands.ChannelModeCommand; + +/** + * ModeReply is really a factory that passes the ModeReply off to a + * ChannelModeCommand. + */ +public class ModeReply extends GenericReply +{ + + /** For use as a factory. */ + public ModeReply() + { + } + + public String getIrcIdentifier() + { + return "324"; + } + + /** + * This is a factory that passes the command off to a + * ChannelModeCommand. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + StringTokenizer tokens = new StringTokenizer( params ); + + // Our nick. We don't need that, I think. + tokens.nextToken(); + + String chan = tokens.nextToken(); + + return new ChannelModeCommand( prefix, chan, tokens ); + } + + /** + * This should, theoretically, never be called, because this command is + * only ever used as a factory. + */ + public boolean updateClientState( ClientState state ) + { + throw new IllegalStateException("This shouldn't be called!" ); + } +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesEndReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesEndReply.java new file mode 100644 index 000000000..a0605b5bd --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesEndReply.java @@ -0,0 +1,47 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +public class NamesEndReply extends GenericReply +{ + + private String channel; + private String comment; + + /** For use as a factory. */ + public NamesEndReply() + { + this( null, null ); + } + + public NamesEndReply( String channel, String comment ) + { + this.channel = channel; + this.comment = comment; + } + + public String getIrcIdentifier() + { + return "366"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NamesEndReply( getParameter( params, 1 ), getParameter( params, 2 ) ); + } + + public String getChannel() + { + return channel; + } + + public String getComment() + { + return comment; + } + +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesReply.java new file mode 100644 index 000000000..acd5045f6 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesReply.java @@ -0,0 +1,89 @@ +package f00f.net.irc.martyr.replies; + +import java.util.List; +import java.util.Arrays; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; +import java.util.logging.Logger; + +public class NamesReply extends GenericReply +{ + static Logger log = Logger.getLogger(NamesReply.class.getName()); + + private List names; + private String channel; + + /** For use as a factory. */ + public NamesReply() + { + } + + public NamesReply( String channel, List names ) + { + this.names = names; + this.channel = channel; + } + + public String getIrcIdentifier() + { + return "353"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NamesReply( getParameter( params, 2 ), Arrays.asList(getParameter( params, 3 ).split(" ")) ); + } + + /** + * Adds the list of names to the client state. + */ + public boolean updateClientState( ClientState state ) + { + boolean stateChanged = false; + + // 1) Get the Channel + Channel channelObj = state.getChannel( channel ); + + if( channel == null ) + { + log.severe("NamesReply: Channel is null"); + return false; + } + + if( channelObj == null ) + { + log.severe("NamesReply: No channel object for channel: " + channel); + return false; + } + + + // 2) Parse out names + for (String nick : names) { + // 3) Check that the user is not already in the list + if( !channelObj.isMemberInChannel( nick ) ) + { + channelObj.addMember( nick, this ); + stateChanged = true; + } + } + + return stateChanged; + } + + public List getNames() + { + return names; + } + + public String getChannel() + { + return channel; + } + +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NowAwayReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NowAwayReply.java new file mode 100644 index 000000000..012431112 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NowAwayReply.java @@ -0,0 +1,43 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +/** + * Signals that you were successfully marked un-away. + * + * @author Daniel Henninger + */ +public class NowAwayReply extends GenericReply +{ + + /* Should always be You have been marked as being away */ + private String message; + + /** + * Factory constructor. + */ + public NowAwayReply() + { + } + + public NowAwayReply(String message) + { + this.message = message; + } + + public String getIrcIdentifier() + { + return "306"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new NowAwayReply(getParameter(params, 0)); + } + + public String getMessage() + { + return message; + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/TopicInfoReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/TopicInfoReply.java new file mode 100644 index 000000000..311e17dc8 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/TopicInfoReply.java @@ -0,0 +1,80 @@ +package f00f.net.irc.martyr.replies; + +import java.util.Date; +import java.util.StringTokenizer; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.clientstate.ClientState; + +/** + * Contains info about the topic, who set it and when. + */ +public class TopicInfoReply extends GenericReply +{ + private String channelName; + private Date date; + private String author; + + /** For use as a factory. */ + public TopicInfoReply() + { + } + + public TopicInfoReply( String channelName, Date date, String author ) + { + this.channelName = channelName; + this.date = date; + this.author = author; + } + + public String getIrcIdentifier() + { + return "333"; + } + + public String getChannel() + { + return this.channelName; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + StringTokenizer tokens = new StringTokenizer( params ); + + // Our nick. We don't need that, I think. + tokens.nextToken(); + + // The channel. + String chan = tokens.nextToken(); + + // The author + String author = tokens.nextToken(); + + // The date. + Date date; + try + { + date = new Date( Long.parseLong( tokens.nextToken() ) * 1000 ); + } + catch( NumberFormatException nfe ) + { + // riiiight... + date = new Date(0); + } + + return new TopicInfoReply( chan, date, author ); + } + + public boolean updateClientState( ClientState state ) + { + Channel channel = state.getChannel( channelName ); + channel.setTopicDate( date ); + channel.setTopicAuthor( author ); + return true; + } +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnAwayReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnAwayReply.java new file mode 100644 index 000000000..f4652f0ce --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnAwayReply.java @@ -0,0 +1,43 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; + +/** + * Signals that you were successfully marked un-away. + * + * @author Daniel Henninger + */ +public class UnAwayReply extends GenericReply +{ + + /* Should always be You are no longer marked as being away */ + private String message; + + /** + * Factory constructor. + */ + public UnAwayReply() + { + } + + public UnAwayReply(String message) + { + this.message = message; + } + + public String getIrcIdentifier() + { + return "305"; + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new UnAwayReply(getParameter(params, 0)); + } + + public String getMessage() + { + return message; + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnknownReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnknownReply.java new file mode 100644 index 000000000..f4ebc14d6 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnknownReply.java @@ -0,0 +1,66 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.commands.UnknownCommand; + + +/** + * A container for unknown replies. + */ +public class UnknownReply extends UnknownCommand +{ + private String replyStr; + private int replyCode; + + public UnknownReply( String ident ) + { + replyStr = ident; + replyCode = Integer.parseInt( ident ); + } + + public int getReplyCode() + { + return replyCode; + } + + public String getReply() + { + return replyStr; + } + + public static boolean isReply( String ident ) + { + char c = ident.charAt(0); + return ( c == '0' || c == '2' || c == '3' ); + } + + public State getState() + { + return State.UNKNOWN; + } + + /** + * Never parsed. + */ + public InCommand parse( String prefix, String identifier, String params ) + { + throw new UnsupportedOperationException("UnknownReply does no parsing."); + } + + /** + * Unknown, so we don't know what the identifier is ahead of time. + */ + public String getIrcIdentifier() + { + return replyStr; + } + + public String toString() + { + return "UnknownReply[" + replyStr + "]"; + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisChannelsReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisChannelsReply.java new file mode 100644 index 000000000..0eee5eb2f --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisChannelsReply.java @@ -0,0 +1,70 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.ParameterIterator; +import java.util.HashSet; +import java.util.Set; +import java.util.StringTokenizer; + +//import org.apache.log4j.Logger; + +public class WhoisChannelsReply extends AbstractWhoisReply +{ + //static Logger log = Logger.getLogger(WhoisChannelsReply.class); + + private String channels; + + /** + * Factory constructor. + * */ + public WhoisChannelsReply() + { + } + + public WhoisChannelsReply( String params ) + { + super( params ); + } + + public String getIrcIdentifier() + { + return "319"; + } + + /** + * @return a space-delimited list of channels + * */ + public String getChannels() + { + return channels; + } + + /** + * @return a set of Strings of channels + * */ + public Set getChannelSet() + { + StringTokenizer tokens = new StringTokenizer( channels ); + Set set = new HashSet(); + while( tokens.hasMoreTokens() ) + { + set.add( tokens.nextToken() ); + } + + return set; + } + + protected void parseParams( ParameterIterator pi ) + { + channels = pi.last(); // Channels + + //log.debug("WhoisChannelsReply: channels: " + channels); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new WhoisChannelsReply( params ); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisEndReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisEndReply.java new file mode 100644 index 000000000..ce9def847 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisEndReply.java @@ -0,0 +1,37 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.ParameterIterator; + +public class WhoisEndReply extends AbstractWhoisReply +{ + /** + * Factory constructor. + * */ + public WhoisEndReply() + { + } + + public WhoisEndReply( String params ) + { + super( params ); + } + + public String getIrcIdentifier() + { + return "318"; + } + + + protected void parseParams( ParameterIterator pi ) + { + // nothing to do here + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new WhoisEndReply( params ); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisIdleReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisIdleReply.java new file mode 100644 index 000000000..aba98205d --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisIdleReply.java @@ -0,0 +1,68 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.ParameterIterator; +import java.util.Date; + +//import org.apache.log4j.Logger; + +public class WhoisIdleReply extends AbstractWhoisReply +{ + //static Logger log = Logger.getLogger(WhoisIdleReply.class); + + private int idleTime; + private Date loginTime; + + /** + * Factory constructor. + * */ + public WhoisIdleReply() + { + } + + public WhoisIdleReply( String params ) + { + super( params ); + } + + public String getIrcIdentifier() + { + return "317"; + } + + /** + * @return seconds idle + * */ + public int getIdleTime() + { + return idleTime; + } + + /** + * @return login time, if provided, null otherwise + * */ + public Date getLoginTime() + { + return loginTime; + } + + protected void parseParams( ParameterIterator pi ) + { + String idleTimeStr = (String)pi.next(); // Idle name + idleTime = Integer.parseInt( idleTimeStr ); + if( pi.hasNext() && ! pi.nextIsLast() ) + { + String loginTimeStr = (String)pi.next(); // Idle description + loginTime = new Date( Long.parseLong( loginTimeStr ) * 1000 ); + } + //log.debug("WhoisIdleReply: idle: " + idleTime); + //log.debug("WhoisIdleReply: login: " + loginTime); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new WhoisIdleReply( params ); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisServerReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisServerReply.java new file mode 100644 index 000000000..d1f4d6344 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisServerReply.java @@ -0,0 +1,61 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.ParameterIterator; +//import org.apache.log4j.Logger; + +public class WhoisServerReply extends AbstractWhoisReply +{ + //static Logger log = Logger.getLogger(WhoisServerReply.class); + + private String serverName; + private String serverDesc; + + /** + * Factory constructor. + * */ + public WhoisServerReply() + { + } + + public WhoisServerReply( String params ) + { + super( params ); + } + + public String getIrcIdentifier() + { + return "312"; + } + + /** + * @return the DNS name of the server + * */ + public String getServerName() + { + return serverName; + } + + /** + * @return the free-form description of the server + * */ + public String getServerDescription() + { + return serverDesc; + } + + protected void parseParams( ParameterIterator pi ) + { + serverName = (String)pi.next(); // Server name + serverDesc = (String)pi.next(); // Server description + //log.debug("WhoisServerReply: server name: " + serverName); + //log.debug("WhoisServerReply: server desc: " + serverDesc); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new WhoisServerReply( params ); + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisUserReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisUserReply.java new file mode 100644 index 000000000..a896c65e6 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisUserReply.java @@ -0,0 +1,54 @@ +package f00f.net.irc.martyr.replies; + +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.util.ParameterIterator; + +public class WhoisUserReply extends AbstractWhoisReply +{ + + private String host; + private String name; + + /** + * Factory constructor. + * */ + public WhoisUserReply() + { + } + + public WhoisUserReply( String params ) + { + super( params ); + } + + public String getIrcIdentifier() + { + return "311"; + } + + protected void parseParams( ParameterIterator pi ) + { + pi.next(); // throw away the nick + host = (String)pi.next(); // hostmask + //log.debug("WhoisUserReply: host: " + host); + name = pi.last(); // the "Name" + //log.debug("WhoisUserReply: name: " + name); + } + + public InCommand parse( String prefix, String identifier, String params ) + { + return new WhoisUserReply( params ); + } + + public String getHost() + { + return host; + } + + public String getName() + { + return name; + } + +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoJoin.java b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoJoin.java new file mode 100644 index 000000000..786552a7b --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoJoin.java @@ -0,0 +1,157 @@ +/* + * Original version: Ben Damm + * Changes by: Morgan Christiansson + * - Spotted bugs + * - Added timer + * - Responds to Invites + * - Re-tries a join with a bad key + * + * Note: Requires Java 1.4 + */ +package f00f.net.irc.martyr.services; + +import f00f.net.irc.martyr.GenericAutoService; +import f00f.net.irc.martyr.IRCConnection; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.TimerTaskCommand; +import f00f.net.irc.martyr.clientstate.Channel; +import f00f.net.irc.martyr.commands.InviteCommand; +import f00f.net.irc.martyr.commands.JoinCommand; +import f00f.net.irc.martyr.commands.KickCommand; +import f00f.net.irc.martyr.errors.GenericJoinError; + +/** + *

AutoJoin joins a group if the IRCConnection is ready. It will wait until + * it is ready if it is not (by waiting for the REGISTERED state change).

+ * + *

AutoJoin maintains a persistent Join (re-join if kicked). + * AutoJoin can cease to be persistent by calling the 'disable' + * method.

+ */ +public class AutoJoin extends GenericAutoService +{ + //static Logger log = Logger.getLogger(AutoJoin.class); + + private String channel = null; + private String key = null; + private TimerTaskCommand joinTimerTask = null; + private long joinTimerTaskDelay = 10*1000; + + public AutoJoin( IRCConnection connection, String channel ) + { + this( connection, channel, null ); + } + + public AutoJoin( IRCConnection connection, String channel, String key ) + { + super( connection ); + + this.channel = channel; + this.key = key; + + enable(); + + updateState( connection.getState() ); + } + + protected void updateState( State state ) + { + + if( state == State.REGISTERED ) + performJoin(); + } + + protected void updateCommand( InCommand command_o ) + { + if( command_o instanceof KickCommand ) + { + KickCommand kickCommand = (KickCommand)command_o; + + if( kickCommand.kickedUs( getConnection().getClientState() ) ) + { + if( Channel.areEqual(kickCommand.getChannel(), channel)) + { + performJoin(); + } + else + { + // mog: TODO: Should we really join a channel for which we aren't the AutoJoin:er? + // BD: You are quite right, this AutoJoin should only worry about itself. + // getConnection().sendCommand( new JoinCommand( kickCommand.getChannel() ) ); + } + } + } + else if(command_o instanceof GenericJoinError ) + { + GenericJoinError joinErr = (GenericJoinError)command_o; + + if( Channel.areEqual( joinErr.getChannel(), channel ) ) + { + //log.debug("AutoJoin: Failed to join channel: "+joinErr.getComment()); + scheduleJoin(); + } + } + else if( command_o instanceof InviteCommand ) + { + InviteCommand invite = (InviteCommand)command_o; + if(!getConnection().getClientState().isOnChannel(invite.getChannel())) + { + performJoin(); + } + } + } + + /** + * Sets up and sends the join command. + * */ + protected synchronized void performJoin() + { + setupJoin(); + sendJoinCommand(); + } + + /** + * Performs various tasks immediatly prior to sending a join command. + * Called from performJoin. + * */ + protected void setupJoin() + { + if(joinTimerTask != null) + { + joinTimerTask.cancel(); + joinTimerTask = null; + } + } + + /** + * This method sends the actual command. Called from performJoin. + * */ + protected void sendJoinCommand() + { + getConnection().sendCommand( new JoinCommand( channel, key ) ); + } + + protected void scheduleJoin() + { + if(joinTimerTask == null || !joinTimerTask.isScheduled()) + { + joinTimerTask = new TimerTaskCommand(getConnection(), new JoinCommand(channel, key)); + //TODO back off delay on repeated retries? + getConnection().getCronManager().schedule(joinTimerTask, joinTimerTaskDelay); + } + } + + public String toString() + { + if( key == null ) + return "AutoJoin [" + channel + "]"; + return "AutoJoin [" + channel + "," + key + "]"; + } + + // END AutoResponder +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoReconnect.java b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoReconnect.java new file mode 100644 index 000000000..06ff33f70 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoReconnect.java @@ -0,0 +1,271 @@ +package f00f.net.irc.martyr.services; + +import java.io.IOException; + +import f00f.net.irc.martyr.IRCConnection; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.GenericAutoService; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.commands.QuitCommand; + +/** + *

AutoReconnect performs the job of reconnecting to the server, if + * the connection is terminated unexpectedly. AutoReconnect + * will try to reconnect 5 times, and then give up. If AutoReconnect + * intercepts a QUIT command before the state change that is issued by + * us (bounced back from the server) then it will not try to + * reconnect.

+ * + *

Note that AutoReconnect has no play in nick negotiation, and as + * such, a failed nick negotiation does not count as a connection + * retry.

+ * + *

Testing note: Does a server send a QUIT before a forceful + * removal from the network? Should AutoReconnect not intercept + * QUITs? Certainly not all servers send QUITs even when you QUIT on + * your own; this class should be put into a command-out chain as well.

+ */ +public class AutoReconnect extends GenericAutoService +{ + //static Logger log = Logger.getLogger(AutoReconnect.class); + + private int attempt; + private int maxAttempts; + private int sleepTime; + private boolean disableOnQuit; + + // How many times to try reconnecting? + public static final int DEFAULT_MAX_ATTEMPTS = 5; + // TODO This is a rather simplistic method, personally I would like to + // see a version of this class that implements a backoff algorithm. + + // If we tried to connect, but failed, how long do we wait until we + // try again (ms)? + public static final int DEFAULT_CONNECT_SLEEPTIME = 1000; + + // If we get a QUIT command from the server notifying us that we have + // QUIT, then self-disable so that we don't reconnect. + public static final boolean DEFAULT_DISABLE_ON_QUIT = true; + + /** + * @param connection The IRCConnection + * @param maxAttempts The number of tries to do before giving up + * @param sleepBetween Milliseconds to sleep between retries + * @param disableOnQuit Automatically disable on quit event + */ + public AutoReconnect( IRCConnection connection, int maxAttempts, + int sleepBetween, boolean disableOnQuit ) + { + super( connection ); + + this.disableOnQuit = disableOnQuit; + this.maxAttempts = maxAttempts; + this.sleepTime = sleepBetween; + this.attempt = 0; + + enable(); + } + + public AutoReconnect( IRCConnection connection, int maxAttempts, + int sleepBetween ) + { + this( connection, maxAttempts, sleepBetween, DEFAULT_DISABLE_ON_QUIT ); + } + + /** + * Initializes with reasonable defaults. + * + * @param connection Connection we are associated with + */ + public AutoReconnect( IRCConnection connection ) + { + this( connection, DEFAULT_MAX_ATTEMPTS, DEFAULT_CONNECT_SLEEPTIME ); + } + + /** + * Attempts to connect, returning only when a connection has been made + * or repeated connections have failed. + * + * @param server Server to connect to + * @param port Port to connect to + * */ + public void go( String server, int port ) + { + doConnectionLoop( server, port ); + } + + /** + * Attempts a single connection to the server. The connection is done + * by asking the client state what server and port we are supposed to + * be connected to, and then calling IRCConnection.connect(...). + * + * @throws IOException if we could not connect successfully + * */ + protected void connect() + throws IOException + { + ClientState cstate = getConnection().getClientState(); + connect( cstate.getServer(), cstate.getPort() ); + } + + /** + * Attempts a single connection to the server. + * + * @param server Server to connect to + * @param port Port to connect to + * @throws IOException if we could not connect successfully + * */ + protected void connect( String server, int port ) + throws IOException + { + getConnection().connect( server, port ); + } + + protected void updateState( State state ) + { + //log.debug("AutoReconnect: Update with state " + state); + if( state == State.UNCONNECTED ) + { + // This should only happen if we were connected and then + // disconnected. Try connecting. + + // failedToConnect() prevents insane-reconnecting loop if + // we never registered, however, it introduces a delay if we + // were registered properly previously + if (failedToConnect(null)) + doConnectionLoop(); + } else if( state == State.REGISTERED ) { + this.attempt = 0; + } + + //log.debug("AutoReconnect: Returned from " + state); + } + + /** + * Calls connect() followed by failedToConnect(...) until a connection + * is made. Gets the server and port from the client state, implying + * that a connection was already attempted before. + * */ + protected void doConnectionLoop() + { + // Tell called proc to use client state info + doConnectionLoop( null, -1 ); + } + + /** + * Calls connect() followed by failedToConnect(...) until a connection + * is made, or the service is disabled. + * + * @param server Server to connect to + * @param port Port to connect to + * */ + protected void doConnectionLoop( String server, int port ) + { + boolean keeptrying = true; + + while( keeptrying && enabled ) + { + Exception error = null; + try + { + if( server == null ) + { + // Try getting the info from the client state + connect(); + } + else + { + connect( server, port ); + } + keeptrying = false; + } + catch( Exception e ) + { + error = e; + keeptrying = true; + } + + if( keeptrying ) + { + keeptrying = failedToConnect( error ); + } + } + } + + /** + * Called when the final failure has occurred. Default implementation + * does nothing. + * */ + protected void finalFailure() + { + //log.debug("AutoReconnect: Final failure."); + this.attempt = 0; + } + + /** + * Called when a failure to connect occurs. This method should do + * whatever needs to be done between connection attempts; usually this + * will be sleeping the current thread and checking if we should stop + * trying to reconnect. + * + * @param error Exception that caused the failure + * @return true if another attempt at connecting should occur + * */ + protected boolean failedToConnect( Exception error ) + { + //log.debug("AutoReconnect: Error connecting: " + error); + + this.attempt++; + + // abort if we've tried too many times + if( attempt >= maxAttempts ) + { + //log.debug("AutoReconnect: Tried " + attempt + " times, giving up."); + finalFailure(); + return false; + } + + // Well, try again damnit! + // Sleep for a bit first. + try + { + Thread.sleep( sleepTime ); + } + catch( InterruptedException ie ) + { + // And we're going to do what? + return false; + } + + return true; + } + + /** + * AutoReconnect will disable itself if it sees a quit command + * generated by returned from the server. This usually happens just + * before the server terminates the connection. Note that this would + * really be better if we could intercept messages on their way out, + * but Martyr doesn't do that. + */ + protected void updateCommand( InCommand command ) + { + if( disableOnQuit + && command instanceof QuitCommand + && ((QuitCommand)command).isOurQuit(getConnection().getClientState()) ) + { + //log.debug("AutoReconnect: Disabling due to receiving own QUIT."); + disable(); + } + } + + public String toString() + { + return "AutoReconnect [" + attempt + "]"; + } + +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoRegister.java b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoRegister.java new file mode 100644 index 000000000..f0cec08ba --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoRegister.java @@ -0,0 +1,289 @@ +package f00f.net.irc.martyr.services; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import f00f.net.irc.martyr.IRCConnection; +import f00f.net.irc.martyr.InCommand; +import f00f.net.irc.martyr.GenericAutoService; +import f00f.net.irc.martyr.State; +import f00f.net.irc.martyr.TimerTaskCommand; +import f00f.net.irc.martyr.clientstate.ClientState; +import f00f.net.irc.martyr.commands.NickCommand; +import f00f.net.irc.martyr.commands.UserCommand; +import f00f.net.irc.martyr.commands.PassCommand; +import f00f.net.irc.martyr.errors.NickInUseError; +import f00f.net.irc.martyr.util.FullNick; +import java.util.logging.Logger; + +/** + *

AutoRegister performs the task of registering the user with the server + * once connected, including finding an appropriate nickname to use if the + * desired one is taken.

+ * + *

AutoRegister's default behaviour is to send the provided nickname. If it + * receives an ERR_NICKNAMEINUSE while unregistered, AutoRegister will try + * again, with an _ appended to the nick. If this fails five times, + * AutoRegister will ask the IRCConnection to disconnect(). Note that if it + * fails to connect it remains enabled, so that if IRCConnection.connect() is + * called, it will re-try the same 5 NICKs.

+ * + *

This default behaviour can be overridden by subclassing AutoRegister and + * overriding the getNickIterator( String baseNick ) method. It returns an + * instance of the java.util.Iterator interface which supplies nicknames (each + * object retreived from the Iterator is presumed to be a String). + * AutoRegister will iterate through the nickname list until there are no more + * items, at which point it will stop. For simple tasks such as providing a + * custom way to form new nicknames, overriding getNickIterator is + * sufficient.

+ * + *

AutoRegister will add itself as a state observer and as a command + * observer. It needs to receive the error.NickInUseError command so that + * it can re-try the registration, and it needs to detect when we + * transition into the UNREGISTERED state.

+ * + *

AutoRegister should be created before the IRCConnection.connect() + * is called. AutoRegister can be disabled by calling the 'disable()' + * method at any time. This simply removes AutoRegister as an + * observer for the state and commands.

+ * + */ +public class AutoRegister extends GenericAutoService +{ + static Logger log = Logger.getLogger(AutoRegister.class.getName()); + + // I've lost track of why the timer stuff was in here. I think the + // original purpose was to make AutoRegister take control of the nick + // more *after* registration occurred. This code is now causing so + // many problems *before* registration, that I think it may need to be + // pulled out. Maybe time to bring a "Manager" service into the + // fold? + private long nickTimerTaskDelay = 10*1000; + private TimerTaskCommand nickTimerTask; + + // Kept so it can be passed to getNickIterator() + private String originalNick; + // Used to set the client state once we register properly. + private String lastTryNick = null; + // Passed to the server on login + private String user; + private String name; + private String pass; + // Our list of nicks. + private Iterator nickIterator = null; + // attempt is only used for the debug output. + private int attempt = 0; + + public static final int MAX_ATTEMPTS = 5; + + public AutoRegister( IRCConnection connection, String nick, + String user, String name ) + { + super( connection ); + + this.originalNick = nick; + this.user = user; + this.name = name; + this.pass = null; + + enable(); + } + + public AutoRegister( IRCConnection connection, String nick, + String user, String name, String pass) + { + super( connection ); + + this.originalNick = nick; + this.user = user; + this.name = name; + this.pass = pass; + + enable(); + } + + + /** + *

This method supplies an Iterator that generates nicknames. Each successive + * failed attempt to login to the server with a nickname will be met with a new + * try using the next nickname in the iterator. When there are no more + * nicknames in the Iterator, AutoRegister gives up. Defining the Iterator as + * an anonymous class works well.

+ * + *

The iterator should iterate over String objects.

+ * + * @param baseNick The nickname passed into the constructor. + * @return Iterator over other attempts of nicks to try + */ + protected Iterator getNickIterator( final String baseNick ) + { + // This is simple and clean.. define the nick generation scheme as an + // anonymous class. + return new UnderscoreIterator(baseNick); + } + + private static class UnderscoreIterator implements Iterator + { + int count = 1; + String nick; + + public UnderscoreIterator( String base ) + { + this.nick = base; + } + + public boolean hasNext() + { + return count <= MAX_ATTEMPTS; + } + + public Object next() + { + if( hasNext() ) + { + String result = nick; + + // Set up the next round + nick = nick + "_"; + ++count; + + // return the value for this round. + return result; + } + else + { + throw new NoSuchElementException("No more nicknames"); + } + } + + public void remove() + { + throw new UnsupportedOperationException(); + } + } + + protected void updateState( State state ) + { + //log.debug("AutoRegister: Update with state " + state); + if( state == State.UNREGISTERED ) + { + // We need to do some registerin'! + nickIterator = getNickIterator( originalNick ); + attempt = 0; + doRegister(); + } + else if( state == State.REGISTERED ) + { + // We need to update the client state. + ClientState clientState = getConnection().getClientState(); + clientState.setNick( new FullNick( lastTryNick ) ); + clientState.setName( name ); + clientState.setUser( user ); + clientState.setPass( pass ); + } + + //log.debug("AutoRegister: Returned from " + state); + } + + protected void updateCommand( InCommand command ) + { + // First, check the state, because if we are already registered + // then none of this matters. + //if( getConnection().getState() == State.REGISTERED ) + //{ + // // We're registered. + // // No reason to continue. + // return; + //} + + if( command instanceof NickInUseError) + { + // If we get an error, then try another nick + NickInUseError nickErr = (NickInUseError)command; + if(nickErr.getNick().getNick().equals(originalNick)) + { + cancelNickAttempt(); // We don't want more than one of these + + scheduleNickAttempt(); + } + if(getConnection().getState() == State.UNREGISTERED ) + { + // re-register. + doRegister(); + } + } + else if( command instanceof NickCommand ) + { + // If we get a nick... then cancel a pending change + NickCommand nickCmd = (NickCommand)command; + if( nickCmd.getOldNick().equalsIgnoreCase( originalNick ) ) + { + cancelNickAttempt(); + } + } + } + + /** + * + */ + private void scheduleNickAttempt() + { + if( getConnection().getState().equals(State.REGISTERED)) + { + // We're already connected. + // We're short-circuiting + return; + } + if(nickTimerTask == null || !nickTimerTask.isScheduled()) + { + nickTimerTask = new TimerTaskCommand(getConnection(), new NickCommand(originalNick)); + //TODO back off delay on repeated retries? + getConnection().getCronManager().schedule(nickTimerTask, nickTimerTaskDelay); + } + } + + private void cancelNickAttempt() + { + if(nickTimerTask != null && nickTimerTask.isScheduled()) + { + nickTimerTask.cancel(); + } + } + + private void doRegister() + { + if( getConnection().getState() != State.UNREGISTERED ) + { + log.severe("AutoRegister: Tried to register but we are not UNREGISTERED"); + return; + } + + if( ! nickIterator.hasNext() ) + { + log.info("AutoRegister: Failed to register."); + getConnection().disconnect(); + return; + } + + lastTryNick = (String)nickIterator.next(); + ++attempt; + log.info("AutoRegister: Trying to register as " + lastTryNick); + + if (pass != null) { + getConnection().sendCommand( new PassCommand( pass )); + } + getConnection().sendCommand( new NickCommand( lastTryNick ) ); + getConnection().sendCommand( new UserCommand( user, name, getConnection() ) ); + } + + public String toString() + { + return "AutoRegister [" + attempt + "]"; + } + + // END AutoRegister +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoResponder.java b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoResponder.java new file mode 100644 index 000000000..08f3a7f29 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoResponder.java @@ -0,0 +1,82 @@ +package f00f.net.irc.martyr.services; + +import java.util.Observable; +import java.util.Observer; + +import f00f.net.irc.martyr.IRCConnection; +import f00f.net.irc.martyr.commands.ChannelModeCommand; +import f00f.net.irc.martyr.commands.JoinCommand; +import f00f.net.irc.martyr.commands.PingCommand; +import f00f.net.irc.martyr.commands.PongCommand; + +/** + * AutoResponder is where commands that should be auto-responded (such + * as PING-PONG) should go. + */ +public class AutoResponder implements Observer +{ + + private IRCConnection connection; + private boolean enabled = false; + + public AutoResponder( IRCConnection connection ) + { + this.connection = connection; + enable(); + } + + public void enable() + { + if( enabled ) + return; + + connection.addCommandObserver( this ); + enabled = true; + } + + public void disable() + { + if( !enabled ) + return; + + connection.removeCommandObserver( this ); + enabled = false; + } + + /** + * Does the work of figuring out what to respond to. + * If a PING is received, send a PONG. If we JOIN a channel, send a + * request for modes. + * */ + public void update( Observable observer, Object updated ) + { + + if( updated instanceof PingCommand ) + { + // We need to do some pongin'! + PingCommand ping = (PingCommand)updated; + + String response = ping.getPingSource(); + + connection.sendCommand( new PongCommand( response ) ); + } + else if( updated instanceof JoinCommand ) + { + // Determine if we joined, and if we did, trigger a MODE discovery + // request. + JoinCommand join = (JoinCommand)updated; + + if( join.weJoined( connection.getClientState() ) ) + { + connection.sendCommand( + new ChannelModeCommand( join.getChannel() ) ); + } + } + } + + // END AutoResponder +} + + + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/util/CtcpUtil.java b/EssentialsUpdate/src/f00f/net/irc/martyr/util/CtcpUtil.java new file mode 100644 index 000000000..ed31c46e7 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/util/CtcpUtil.java @@ -0,0 +1,99 @@ +package f00f.net.irc.martyr.util; + +import java.util.NoSuchElementException; + +public class CtcpUtil +{ + public static final char CTCP_TAG_DELIM = '\001'; + + /** + * Returns a new string ready for sending via MessageCommand. + * + * @param action Action string to create + * @return Action string ready for sending + */ + public static String makeActionString( String action ) + { + return makeCtcpString( "ACTION " + action ); + } + + public static String makeCtcpString( String s ) + { + return "" + CTCP_TAG_DELIM + s + CTCP_TAG_DELIM; + } + + /** + * Parses the string into tokens, where each token is either a + * CTCP escaped sequence or not. + */ + public static class CtcpTokenizer + { + private String str; + + public CtcpTokenizer( String in ) + { + this.str = in; + } + + public boolean isNextACtcp() + { + return str.charAt(0) == CTCP_TAG_DELIM; + } + + public boolean hasNext() + { + return !str.equals(""); + } + + public String next() + { + return nextToken(); + } + public String nextToken() + { + if( !hasNext() ) + { + throw new NoSuchElementException(); + } + + int pos = str.indexOf( CTCP_TAG_DELIM, 1 ); + String result; + if( isNextACtcp() ) + { + if( pos < 0 ) + { + // Error? Well, whatever, return the rest of the + // string. + result = str.substring( 1 ); + str = ""; + return result; + } + else + { + // ^Aour string^A(rest of string) + // Lose both ^A + result = str.substring( 1, pos ); + str = str.substring( pos + 1 ); + return result; + } + } + else + { + // Not a CTCP + if( pos < 0 ) + { + result = str; + str = ""; + return result; + } + else + { + result = str.substring( 0, pos ); + str = str.substring( pos ); + return result; + } + } + } + } +} + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/util/FullNick.java b/EssentialsUpdate/src/f00f/net/irc/martyr/util/FullNick.java new file mode 100644 index 000000000..c83cd98d4 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/util/FullNick.java @@ -0,0 +1,159 @@ +package f00f.net.irc.martyr.util; + +import java.util.StringTokenizer; + +/** + * Parses out a full nick (ex: sork<exclaimation>sork<at>f00f.net) and stores it for + * use. It also provides a consistent hashing method. + */ +public class FullNick +{ + + private String nick; + private String user; + private String remotehost; + + private String original; + + public FullNick( String original ) + { + this.original = original; + parse( original ); + } + + + /** + * It can't deal with parameters that have no '!'. When given a parameter with + * no '!', it simply places the entire string into the 'nick' field. FullNick + * is intended to be immutable. + * + * TODO: Should this enforce proper nick syntax? + * @param original Original nick we will parse + */ + private void parse( String original ) + { + if( original == null ) + return; + + StringTokenizer tokens = new StringTokenizer( original, "!", false ); + + nick = tokens.nextToken(); + + if( tokens.hasMoreTokens() ) + { + user = tokens.nextToken("@"); + if( user.charAt(0) == '!' ) + user = user.substring(1); + } + + if( tokens.hasMoreTokens() ) + { + remotehost = tokens.nextToken(""); + if( remotehost.charAt(0) == '@' ) + remotehost = remotehost.substring(1); + } + } + + public String getNick() + { + return nick; + } + + public String getUser() + { + return user; + } + + public String getHost() + { + return remotehost; + } + + public String getSource() + { + //return nick+"!"+user+"@"+remotehost; + return original; + } + + + public int hashCode() + { + if( nick == null ) + return 0; + + return nick.hashCode(); + } + + /** + * Performs case insesitive equals on the nicks only. Does not strip + * off any leading @ or +. ({ == [ and ] == } and | == \) It appears + * that servers are not RFC complient on this, so we will not as well. + * + * @param nick Nick to compare this nick with + * @return True or false of nick is the same + */ + + public boolean equals( String nick ) + { + if( nick == null ) + return false; + + return nick.equalsIgnoreCase( this.nick ); + } + + public boolean equals( FullNick nick ) + { + if( nick == null ) + return false; + return equals( nick.getNick() ); + } + + public boolean equals( Object object ) + { + if( object instanceof FullNick ) + return equals( (FullNick)object ); + return false; + } + + /** + * @return the nick part + * */ + public String toString() + { + return nick; + } + + /** + * Unit test. + * + * @param args Args passed to program + */ + public static void main( String args[] ) + { + + FullNick nick = new FullNick( args[0] ); + + System.out.println( nick.getNick() ); + System.out.println( nick.getUser() ); + System.out.println( nick.getHost() ); + System.out.println( nick.getSource() ); + + if( args.length > 1 ) + { + + FullNick nick2 = new FullNick( args[1] ); + + System.out.println( "" ); + System.out.println( nick2.getNick() ); + System.out.println( nick2.getUser() ); + System.out.println( nick2.getHost() ); + System.out.println( nick2.getSource() ); + + System.out.println( nick2.equals( nick ) ? "Equal." : "Not equal." ); + + } + } + +} + + diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/util/IRCStringUtils.java b/EssentialsUpdate/src/f00f/net/irc/martyr/util/IRCStringUtils.java new file mode 100644 index 000000000..3b4fa6075 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/util/IRCStringUtils.java @@ -0,0 +1,90 @@ +package f00f.net.irc.martyr.util; + +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.ArrayList; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +/** + * @author Daniel Henninger + */ +public class IRCStringUtils +{ + + /** + * Returns the message with all control characters stripped from it. + * + * @param msg Message to remove control chars from. + * @return Stripped form of message. + */ + public static String stripControlChars(String msg) + { + Pattern pa = Pattern.compile("\u0003\\p{Digit}\\p{Digit}"); + Matcher ma = pa.matcher(msg); + Pattern pb = Pattern.compile("\\p{Cntrl}"); + Matcher mb = pb.matcher(ma.replaceAll("")); + return mb.replaceAll(""); + } + + /** + * Returns the message with all formatting characters converted into associated html characters. + * + * TODO: Should actually parse colors. + * @param msg Message to convert to HTML format. + * @return Message in HTML format. + */ + public static String convertToHTML(String msg) + { + CharacterIterator ci = new StringCharacterIterator(msg); + String htmlStr = ""; + ArrayList formatList = new ArrayList(); + for (char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) { + if (c == '\u0002') { + if (formatList.contains("")) { + formatList.remove(""); + htmlStr += ""; + } + else { + formatList.add(""); + htmlStr += ""; + } + } + else if (c == '\u001F') { + if (formatList.contains("")) { + formatList.remove(""); + htmlStr += ""; + } + else { + formatList.add(""); + htmlStr += ""; + } + } + else if (c == '\u0016') { + if (formatList.contains("")) { + formatList.remove(""); + htmlStr += ""; + } + else { + formatList.add(""); + htmlStr += ""; + } + } + else if (c == '\u000F' || c == '\u0015') { + for (String f : formatList) { + htmlStr += f; + } + formatList.clear(); + } + else { + htmlStr += c; + } + } + for (String f : formatList) { + htmlStr += f; + } + formatList.clear(); + return stripControlChars(htmlStr); + } + +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/util/ParameterIterator.java b/EssentialsUpdate/src/f00f/net/irc/martyr/util/ParameterIterator.java new file mode 100644 index 000000000..d1e2c8507 --- /dev/null +++ b/EssentialsUpdate/src/f00f/net/irc/martyr/util/ParameterIterator.java @@ -0,0 +1,124 @@ +/* + * Original author: Ben Damm + * Changes by: Mog + * - Fixed bug with substring handling + * */ +package f00f.net.irc.martyr.util; + + +import java.util.Iterator; +import java.util.NoSuchElementException; + +//TODO: Unit test + +/** + * This class iterates over the parameter string of an IRC command, + * returning each parameter in order as next() is called. This class + * also knows about the ":" parameters, which is the large string at + * the end of most commands, and treats it specially. + */ +public class ParameterIterator implements Iterator +{ + //static Logger log = Logger.getLogger(ParameterIterator.class); + + private String paramStr; + private int position; + private String last = null; + + public ParameterIterator( String paramStr ) + { + //log.debug("ParameterIterator: Params: `" + paramStr + "'"); + // We don't check for null here because hasNext is the place + // to do it, according to the definition for Iterator. + // next() should throw an exception. + if( paramStr != null ) + { + this.paramStr = paramStr.trim(); + position = 0; + } + else + { + this.paramStr = null; + position = -1; + } + } + + /** + * @return true if there are more parameters, and false + * otherwise. + */ + public boolean hasNext() + { + if( paramStr == null ) + return false; + + return position < paramStr.length(); + } + + /** + * @throws NoSuchElementException if there are no more params + * @return true if the next parameter is also the ":" parameter. + * */ + public boolean nextIsLast() + { + if( ! hasNext() ) + { + throw new NoSuchElementException("No more parameters."); + } + return paramStr.charAt(position) == ':'; + } + + /** + * @throws NoSuchElementException if there are no more params + * */ + public Object next() + { + if( ! hasNext() ) + { + throw new NoSuchElementException("No more parameters."); + } + + // If : is the first char, the rest of the string is a + // parameter. + if( paramStr.charAt(position) == ':' ) + { + String result = paramStr.substring(position + 1); + position = paramStr.length(); + last = result; + return result; + } + + int spaceIndex = paramStr.indexOf( ' ', position ); + // We can't have a space after the last parameter, it gets + // trimmed in the constructor. Also, we can't have only + // spaces, so we don't need to check for -1. Finally, we are + // guaranteed to have a space before the colon, so we don't + // have to do any checking at all! + + String result = paramStr.substring( position, spaceIndex ); + position = spaceIndex + 1; + return result; + } + + /** + * Forwards the iterator to the last element and returns it. The + * "last" parameter should be the ":" parameter. + * + * @return Last parameter + * */ + public String last() + { + while( hasNext() ) + next(); + + return last; + } + + public void remove() + { + // hmm, nah. This can be implemented some other time. + throw new UnsupportedOperationException( "Remove on the parameters? Why?" ); + } +} + + diff --git a/EssentialsUpdate/src/plugin.yml b/EssentialsUpdate/src/plugin.yml new file mode 100644 index 000000000..b8dbe8e25 --- /dev/null +++ b/EssentialsUpdate/src/plugin.yml @@ -0,0 +1,21 @@ +# This determines the command prefix when there are conflicts (/name:home, /name:help, etc.) +name: EssentialsUpdate +main: com.earth2me.essentials.update.EssentialsUpdate +# Note to developers: This next line cannot change, or the automatic versioning system will break. +version: TeamCity +description: This plugin allows to install or update all Essentials plugins +authors: [snowleo] +commands: + essentialsupdate: + description: Install or update the Essentials plugins. + usage: / + essentialshelp: + description: Get help from the Essentials support chat. + usage: / +permissions: + essentials.update: + description: Allows you to update Essentials + default: op + essentials.helpchat: + description: Allows you to join Essentials help chat + default: op \ No newline at end of file -- cgit v1.2.3 From 93128712506bb0d4d422553b0480195cfd2cc9b3 Mon Sep 17 00:00:00 2001 From: snowleo Date: Wed, 12 Oct 2011 05:00:36 +0200 Subject: Replacing martyr with Pircbot 1.5 --- .../earth2me/essentials/update/EssentialsHelp.java | 267 +- .../src/com/earth2me/essentials/update/IrcBot.java | 163 ++ .../f00f/net/irc/martyr/ClientStateMonitor.java | 67 - .../src/f00f/net/irc/martyr/Command.java | 18 - .../src/f00f/net/irc/martyr/CommandObserver.java | 5 - .../src/f00f/net/irc/martyr/CommandRegister.java | 118 - .../src/f00f/net/irc/martyr/CommandSender.java | 14 - .../src/f00f/net/irc/martyr/CronManager.java | 80 - .../src/f00f/net/irc/martyr/ForwardObservable.java | 66 - .../f00f/net/irc/martyr/GenericAutoService.java | 54 - .../net/irc/martyr/GenericCommandAutoService.java | 79 - .../src/f00f/net/irc/martyr/IRCConnection.java | 1163 -------- .../src/f00f/net/irc/martyr/InCommand.java | 99 - .../src/f00f/net/irc/martyr/InputHandler.java | 130 - EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java | 103 - .../src/f00f/net/irc/martyr/OutCommand.java | 24 - .../src/f00f/net/irc/martyr/State.java | 31 - .../src/f00f/net/irc/martyr/StateObserver.java | 8 - .../src/f00f/net/irc/martyr/TimerTaskCommand.java | 57 - .../f00f/net/irc/martyr/clientstate/Channel.java | 373 --- .../net/irc/martyr/clientstate/ClientState.java | 193 -- .../f00f/net/irc/martyr/clientstate/Member.java | 114 - .../net/irc/martyr/commands/AbstractCommand.java | 32 - .../net/irc/martyr/commands/AbstractInCommand.java | 174 -- .../f00f/net/irc/martyr/commands/ActionCtcp.java | 12 - .../irc/martyr/commands/ChannelModeCommand.java | 189 -- .../f00f/net/irc/martyr/commands/CtcpMessage.java | 129 - .../f00f/net/irc/martyr/commands/CtcpNotice.java | 131 - .../net/irc/martyr/commands/InviteCommand.java | 90 - .../f00f/net/irc/martyr/commands/IsonCommand.java | 144 - .../f00f/net/irc/martyr/commands/JoinCommand.java | 131 - .../f00f/net/irc/martyr/commands/KickCommand.java | 110 - .../net/irc/martyr/commands/MessageCommand.java | 127 - .../f00f/net/irc/martyr/commands/ModeCommand.java | 237 -- .../f00f/net/irc/martyr/commands/NamesCommand.java | 77 - .../f00f/net/irc/martyr/commands/NickCommand.java | 97 - .../net/irc/martyr/commands/NoticeCommand.java | 129 - .../f00f/net/irc/martyr/commands/PartCommand.java | 126 - .../f00f/net/irc/martyr/commands/PassCommand.java | 33 - .../f00f/net/irc/martyr/commands/PingCommand.java | 67 - .../f00f/net/irc/martyr/commands/PongCommand.java | 39 - .../f00f/net/irc/martyr/commands/QuitCommand.java | 132 - .../f00f/net/irc/martyr/commands/RawCommand.java | 58 - .../f00f/net/irc/martyr/commands/TopicCommand.java | 80 - .../net/irc/martyr/commands/UnknownCommand.java | 38 - .../f00f/net/irc/martyr/commands/UserCommand.java | 46 - .../net/irc/martyr/commands/UserModeCommand.java | 99 - .../net/irc/martyr/commands/WelcomeCommand.java | 125 - .../f00f/net/irc/martyr/commands/WhoisCommand.java | 40 - .../irc/martyr/errors/AlreadyRegisteredError.java | 40 - .../irc/martyr/errors/CannotSendToChanError.java | 47 - .../net/irc/martyr/errors/CantKillServerError.java | 40 - .../irc/martyr/errors/ChanOPrivsNeededError.java | 48 - .../net/irc/martyr/errors/ChannelBannedError.java | 49 - .../irc/martyr/errors/ChannelInviteOnlyError.java | 48 - .../net/irc/martyr/errors/ChannelLimitError.java | 50 - .../irc/martyr/errors/ChannelWrongKeyError.java | 50 - .../irc/martyr/errors/ErroneusNicknameError.java | 47 - .../f00f/net/irc/martyr/errors/FileErrorError.java | 39 - .../f00f/net/irc/martyr/errors/GenericError.java | 14 - .../net/irc/martyr/errors/GenericJoinError.java | 67 - .../f00f/net/irc/martyr/errors/KeySetError.java | 45 - .../net/irc/martyr/errors/LoadTooHighError.java | 49 - .../net/irc/martyr/errors/NeedMoreParamsError.java | 47 - .../net/irc/martyr/errors/NickCollisionError.java | 48 - .../f00f/net/irc/martyr/errors/NickInUseError.java | 63 - .../net/irc/martyr/errors/NoAdminInfoError.java | 47 - .../f00f/net/irc/martyr/errors/NoLoginError.java | 48 - .../f00f/net/irc/martyr/errors/NoMotdError.java | 39 - .../irc/martyr/errors/NoNicknameGivenError.java | 39 - .../net/irc/martyr/errors/NoOperHostError.java | 40 - .../f00f/net/irc/martyr/errors/NoOriginError.java | 40 - .../net/irc/martyr/errors/NoPermForHostError.java | 40 - .../net/irc/martyr/errors/NoPrivilegesError.java | 40 - .../net/irc/martyr/errors/NoRecipientError.java | 38 - .../net/irc/martyr/errors/NoSuchChannelError.java | 46 - .../net/irc/martyr/errors/NoSuchNickError.java | 47 - .../net/irc/martyr/errors/NoSuchServerError.java | 46 - .../net/irc/martyr/errors/NoTextToSendError.java | 41 - .../net/irc/martyr/errors/NoTopLevelError.java | 48 - .../net/irc/martyr/errors/NotOnChannelError.java | 47 - .../net/irc/martyr/errors/NotRegisteredError.java | 40 - .../net/irc/martyr/errors/PasswdMismatchError.java | 40 - .../net/irc/martyr/errors/SummonDisabledError.java | 40 - .../irc/martyr/errors/TooManyChannelsError.java | 46 - .../net/irc/martyr/errors/TooManyTargetsError.java | 47 - .../irc/martyr/errors/UModeUnknownFlagError.java | 40 - .../net/irc/martyr/errors/UnknownCommandError.java | 46 - .../f00f/net/irc/martyr/errors/UnknownError.java | 69 - .../net/irc/martyr/errors/UnknownModeError.java | 45 - .../irc/martyr/errors/UserNotInChannelError.java | 54 - .../net/irc/martyr/errors/UserOnChannelError.java | 54 - .../net/irc/martyr/errors/UsersDisabledError.java | 40 - .../net/irc/martyr/errors/UsersDontMatchError.java | 39 - .../net/irc/martyr/errors/WasNoSuchNickError.java | 47 - .../net/irc/martyr/errors/WildTopLevelError.java | 48 - .../irc/martyr/errors/YoureBannedCreepError.java | 40 - .../src/f00f/net/irc/martyr/modes/GenericMode.java | 77 - .../src/f00f/net/irc/martyr/modes/README | 8 - .../irc/martyr/modes/channel/AnonChannelMode.java | 44 - .../f00f/net/irc/martyr/modes/channel/BanMode.java | 38 - .../irc/martyr/modes/channel/ExceptionMode.java | 38 - .../martyr/modes/channel/GenericChannelMask.java | 16 - .../martyr/modes/channel/GenericChannelMode.java | 23 - .../irc/martyr/modes/channel/InviteMaskMode.java | 30 - .../irc/martyr/modes/channel/InviteOnlyMode.java | 32 - .../f00f/net/irc/martyr/modes/channel/KeyMode.java | 31 - .../net/irc/martyr/modes/channel/LimitMode.java | 31 - .../irc/martyr/modes/channel/ModeratedMode.java | 31 - .../net/irc/martyr/modes/channel/NoExtMsgMode.java | 30 - .../net/irc/martyr/modes/channel/OperMode.java | 31 - .../net/irc/martyr/modes/channel/PrivateMode.java | 50 - .../net/irc/martyr/modes/channel/SecretMode.java | 50 - .../irc/martyr/modes/channel/TopicLockMode.java | 27 - .../net/irc/martyr/modes/channel/VoiceMode.java | 34 - .../net/irc/martyr/modes/user/GenericUserMode.java | 24 - .../net/irc/martyr/modes/user/InvisibleMode.java | 22 - .../net/irc/martyr/replies/AbstractWhoisReply.java | 58 - .../src/f00f/net/irc/martyr/replies/AwayReply.java | 49 - .../irc/martyr/replies/ChannelCreationReply.java | 78 - .../f00f/net/irc/martyr/replies/GenericReply.java | 16 - .../net/irc/martyr/replies/GenericStringReply.java | 23 - .../net/irc/martyr/replies/LUserClientReply.java | 28 - .../f00f/net/irc/martyr/replies/LUserMeReply.java | 28 - .../f00f/net/irc/martyr/replies/LUserOpReply.java | 36 - .../f00f/net/irc/martyr/replies/ListEndReply.java | 31 - .../src/f00f/net/irc/martyr/replies/ListReply.java | 63 - .../net/irc/martyr/replies/ListStartReply.java | 31 - .../src/f00f/net/irc/martyr/replies/ModeReply.java | 54 - .../f00f/net/irc/martyr/replies/NamesEndReply.java | 47 - .../f00f/net/irc/martyr/replies/NamesReply.java | 89 - .../f00f/net/irc/martyr/replies/NowAwayReply.java | 43 - .../net/irc/martyr/replies/TopicInfoReply.java | 80 - .../f00f/net/irc/martyr/replies/UnAwayReply.java | 43 - .../f00f/net/irc/martyr/replies/UnknownReply.java | 66 - .../net/irc/martyr/replies/WhoisChannelsReply.java | 70 - .../f00f/net/irc/martyr/replies/WhoisEndReply.java | 37 - .../net/irc/martyr/replies/WhoisIdleReply.java | 68 - .../net/irc/martyr/replies/WhoisServerReply.java | 61 - .../net/irc/martyr/replies/WhoisUserReply.java | 54 - .../src/f00f/net/irc/martyr/services/AutoJoin.java | 157 -- .../net/irc/martyr/services/AutoReconnect.java | 271 -- .../f00f/net/irc/martyr/services/AutoRegister.java | 289 -- .../net/irc/martyr/services/AutoResponder.java | 82 - .../src/f00f/net/irc/martyr/util/CtcpUtil.java | 99 - .../src/f00f/net/irc/martyr/util/FullNick.java | 159 -- .../f00f/net/irc/martyr/util/IRCStringUtils.java | 90 - .../net/irc/martyr/util/ParameterIterator.java | 124 - .../src/org/jibble/pircbot/Colors.java | 293 ++ .../src/org/jibble/pircbot/InputThread.java | 169 ++ .../src/org/jibble/pircbot/IrcException.java | 35 + .../jibble/pircbot/NickAlreadyInUseException.java | 38 + .../src/org/jibble/pircbot/OutputThread.java | 105 + .../src/org/jibble/pircbot/PircBot.java | 2808 ++++++++++++++++++++ EssentialsUpdate/src/org/jibble/pircbot/Queue.java | 146 + .../src/org/jibble/pircbot/ReplyConstants.java | 176 ++ EssentialsUpdate/src/org/jibble/pircbot/User.java | 161 ++ 157 files changed, 4166 insertions(+), 10946 deletions(-) create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/IrcBot.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/ClientStateMonitor.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/Command.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/CommandObserver.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/CommandRegister.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/CommandSender.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/CronManager.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/ForwardObservable.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/GenericAutoService.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/GenericCommandAutoService.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/IRCConnection.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/InCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/InputHandler.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/OutCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/State.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/StateObserver.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/TimerTaskCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/ActionCtcp.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/ChannelModeCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpMessage.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpNotice.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/InviteCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/IsonCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/JoinCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/KickCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/MessageCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/ModeCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/NamesCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/NickCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/NoticeCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/PartCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/PassCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/PingCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/PongCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/QuitCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/RawCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/TopicCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/UnknownCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserModeCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/WelcomeCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/commands/WhoisCommand.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/AlreadyRegisteredError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/CannotSendToChanError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/CantKillServerError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChanOPrivsNeededError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelBannedError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelInviteOnlyError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelLimitError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelWrongKeyError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/ErroneusNicknameError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/FileErrorError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericJoinError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/KeySetError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/LoadTooHighError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NeedMoreParamsError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickCollisionError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickInUseError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoAdminInfoError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoLoginError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoMotdError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoNicknameGivenError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOperHostError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOriginError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPermForHostError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPrivilegesError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoRecipientError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchChannelError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchNickError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchServerError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTextToSendError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTopLevelError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotOnChannelError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotRegisteredError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/PasswdMismatchError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/SummonDisabledError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyChannelsError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyTargetsError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UModeUnknownFlagError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownCommandError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownModeError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserNotInChannelError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserOnChannelError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDisabledError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDontMatchError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/WasNoSuchNickError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/WildTopLevelError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/errors/YoureBannedCreepError.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/GenericMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/README delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/AnonChannelMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/BanMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ExceptionMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMask.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteMaskMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteOnlyMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/KeyMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/LimitMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ModeratedMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/NoExtMsgMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/OperMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/PrivateMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/SecretMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/TopicLockMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/VoiceMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/GenericUserMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/InvisibleMode.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/AbstractWhoisReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/AwayReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ChannelCreationReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericStringReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserClientReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserMeReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserOpReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListEndReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListStartReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/ModeReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesEndReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/NowAwayReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/TopicInfoReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnAwayReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnknownReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisChannelsReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisEndReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisIdleReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisServerReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisUserReply.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoJoin.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoReconnect.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoRegister.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoResponder.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/util/CtcpUtil.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/util/FullNick.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/util/IRCStringUtils.java delete mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/util/ParameterIterator.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/Colors.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/InputThread.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/IrcException.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/NickAlreadyInUseException.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/OutputThread.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/PircBot.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/Queue.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/ReplyConstants.java create mode 100755 EssentialsUpdate/src/org/jibble/pircbot/User.java (limited to 'EssentialsUpdate/src') diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java b/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java index 5b134b8b8..d70d01a01 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java @@ -1,29 +1,11 @@ package com.earth2me.essentials.update; -import f00f.net.irc.martyr.GenericAutoService; -import f00f.net.irc.martyr.IRCConnection; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.Member; -import f00f.net.irc.martyr.commands.InviteCommand; -import f00f.net.irc.martyr.commands.KickCommand; -import f00f.net.irc.martyr.commands.MessageCommand; -import f00f.net.irc.martyr.commands.NoticeCommand; -import f00f.net.irc.martyr.commands.QuitCommand; -import f00f.net.irc.martyr.commands.TopicCommand; -import f00f.net.irc.martyr.errors.GenericJoinError; -import f00f.net.irc.martyr.services.AutoJoin; -import f00f.net.irc.martyr.services.AutoReconnect; -import f00f.net.irc.martyr.services.AutoRegister; -import f00f.net.irc.martyr.services.AutoResponder; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.Charset; -import java.util.Enumeration; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -39,17 +21,16 @@ import org.bukkit.event.player.PlayerListener; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; +import org.jibble.pircbot.User; public class EssentialsHelp extends PlayerListener { private transient Player chatUser; - private transient IRCConnection connection; - private transient AutoReconnect autoReconnect; - private transient boolean shouldQuit = false; private final transient Server server; private final transient Plugin plugin; private final static Charset UTF8 = Charset.forName("utf-8"); + private transient IrcBot ircBot; public EssentialsHelp(Plugin plugin) { @@ -71,7 +52,7 @@ public class EssentialsHelp extends PlayerListener if (chatUser == null) { chatUser = (Player)sender; - connection = null; + ircBot = null; sender.sendMessage("You will be connected to the Essentials Help Chat."); sender.sendMessage("All your chat messages will be forwarded to the channel. You can't chat with other players on your server while in help chat, but you can use commands."); sender.sendMessage("Please be patient, if noone is available, check back later."); @@ -92,62 +73,69 @@ public class EssentialsHelp extends PlayerListener public void onDisable() { - if (autoReconnect != null && connection != null) + if ( ircBot != null) { - autoReconnect.disable(); - shouldQuit = true; - connection.disconnect(); + ircBot.quit(); + ircBot = null; } } - private void sendChatMessage(final Player player, final String message) + private boolean sendChatMessage(final Player player, final String message) { final String messageCleaned = message.trim(); if (messageCleaned.isEmpty()) { - return; + return false; } - if (connection == null) + if (ircBot == null) { if (messageCleaned.equalsIgnoreCase("yes")) { player.sendMessage("Connecting..."); connectToIRC(player); + return true; } if (messageCleaned.equalsIgnoreCase("no") || message.equalsIgnoreCase("!quit")) { chatUser = null; + return true; } + return false; } else { + if (ircBot.isKicked()) { + chatUser = null; + ircBot.quit(); + ircBot = null; + return false; + } final String lowMessage = messageCleaned.toLowerCase(); if (lowMessage.startsWith("!quit")) { chatUser = null; - autoReconnect.disable(); - shouldQuit = true; - connection.sendCommand(new QuitCommand("Connection closed by user.")); + if (ircBot != null) { + ircBot.quit(); + ircBot = null; + } player.sendMessage("Connection closed."); - return; + return true; } - if (!connection.getClientState().getChannels().hasMoreElements()) + if (!ircBot.isConnected() || ircBot.getChannels().length == 0) { - player.sendMessage("Not connected yet!"); - return; + return false; } if (lowMessage.startsWith("!list")) { - final Enumeration members = ((Channel)connection.getClientState().getChannels().nextElement()).getMembers(); + final User[] members = ircBot.getUsers(); final StringBuilder sb = new StringBuilder(); - while (members.hasMoreElements()) + for (User user : members) { if (sb.length() > 0) { sb.append("§f, "); } - final Member member = (Member)members.nextElement(); - if (member.hasOps() || member.hasVoice()) + if (user.isOp() || user.hasVoice()) { sb.append("§6"); } @@ -155,10 +143,10 @@ public class EssentialsHelp extends PlayerListener { sb.append("§7"); } - sb.append(member.getNick()); + sb.append(user.getPrefix()).append(user.getNick()); } player.sendMessage(sb.toString()); - return; + return true; } if (lowMessage.startsWith("!help")) { @@ -168,37 +156,33 @@ public class EssentialsHelp extends PlayerListener player.sendMessage("!config - Sends your Essentials config to the chat."); player.sendMessage("!list - List all players in chat."); player.sendMessage("!quit - Leave chat."); - return; + return true; } if (lowMessage.startsWith("!errors")) { sendErrors(); - return; + return true; } if (lowMessage.startsWith("!startup")) { sendStartup(); - return; + return true; } if (lowMessage.startsWith("!config")) { sendConfig(); - return; + return true; } - final Channel channel = (Channel)connection.getClientState().getChannels().nextElement(); - connection.sendCommand(new MessageCommand(channel.getName(), messageCleaned)); - chatUser.sendMessage("§6" + connection.getClientState().getNick().getNick() + ": §7" + messageCleaned); + ircBot.sendMessage(messageCleaned); + chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + messageCleaned); + return true; } } - private void connectToIRC(final Player player) + private String buildIrcName() { - connection = new IRCConnection(); - // Required services - new AutoResponder(connection); - int versionNumber = 0; final StringBuilder nameBuilder = new StringBuilder(); - nameBuilder.append(player.getName()); + nameBuilder.append(chatUser.getName()); final Matcher versionMatch = Pattern.compile("git-Bukkit-([0-9]+).([0-9]+).([0-9]+)-[0-9]+-[0-9a-z]+-b([0-9]+)jnks.*").matcher(server.getVersion()); if (versionMatch.matches()) @@ -268,28 +252,12 @@ public class EssentialsHelp extends PlayerListener nameBuilder.append(perm.getDescription().getVersion()); } - new AutoRegister(connection, "Ess_" + player.getName(), "esshelp", nameBuilder.toString()); - - autoReconnect = new AutoReconnect(connection); - new KickAutoJoin(connection, "#essentials"); - - new IRCListener(connection); - autoReconnect.go("irc.esper.net", 6667); + return nameBuilder.toString(); } - private void handleIRCmessage(final String nick, final String message) + private void connectToIRC(final Player player) { - - if (chatUser != null) - { - final StringBuilder sb = new StringBuilder(); - sb.append("§6"); - sb.append(nick); - sb.append(": §7"); - final String coloredmessage = message.replace("\u000300", "§f").replace("\u000301", "§0").replace("\u000302", "§1").replace("\u000303", "§2").replace("\u000304", "§c").replace("\u000305", "§4").replace("\u000306", "§5").replace("\u000307", "§6").replace("\u000308", "§e").replace("\u000309", "§a").replace("\u00030", "§f").replace("\u000310", "§b").replace("\u000311", "§f").replace("\u000312", "§9").replace("\u000313", "§d").replace("\u000314", "§8").replace("\u000315", "§7").replace("\u00031", "§0").replace("\u00032", "§1").replace("\u00033", "§2").replace("\u00034", "§c").replace("\u00035", "§4").replace("\u00036", "§5").replace("\u00037", "§6").replace("\u00038", "§e").replace("\u00039", "§a").replace("\u0003", "§7"); - sb.append(coloredmessage); - chatUser.sendMessage(sb.toString()); - } + ircBot = new IrcBot(player, "Ess_" + player.getName(), buildIrcName()); } private void sendErrors() @@ -312,7 +280,7 @@ public class EssentialsHelp extends PlayerListener FileInputStream fis = new FileInputStream(logFile); if (logFile.length() > 1000000) { - fis.skip(logFile.length()-1000000); + fis.skip(logFile.length() - 1000000); } page = new BufferedReader(new InputStreamReader(fis)); final StringBuilder input = new StringBuilder(); @@ -320,19 +288,20 @@ public class EssentialsHelp extends PlayerListener Pattern pattern = Pattern.compile("^[0-9 :-]+\\[INFO\\].*"); while ((line = page.readLine()) != null) { - if (!pattern.matcher(line).matches()) { + if (!pattern.matcher(line).matches()) + { input.append(line).append("\n"); } } - if (input.length()>10000) { - input.delete(0, input.length()-10000); + if (input.length() > 10000) + { + input.delete(0, input.length() - 10000); } final PastieUpload pastie = new PastieUpload(); final String url = pastie.send(input.toString()); - final Channel channel = (Channel)connection.getClientState().getChannels().nextElement(); String message = "Errors: " + url; - chatUser.sendMessage("§6" + connection.getClientState().getNick().getNick() + ": §7" + message); - connection.sendCommand(new MessageCommand(channel.getName(), message)); + chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message); + ircBot.sendMessage(message); } catch (IOException ex) { @@ -354,7 +323,7 @@ public class EssentialsHelp extends PlayerListener } } } - + private void sendStartup() { BufferedReader page = null; @@ -375,7 +344,7 @@ public class EssentialsHelp extends PlayerListener FileInputStream fis = new FileInputStream(logFile); if (logFile.length() > 1000000) { - fis.skip(logFile.length()-1000000); + fis.skip(logFile.length() - 1000000); } page = new BufferedReader(new InputStreamReader(fis)); final StringBuilder input = new StringBuilder(); @@ -385,28 +354,32 @@ public class EssentialsHelp extends PlayerListener boolean log = false; while ((line = page.readLine()) != null) { - if (patternStart.matcher(line).matches()) { - if (input.length() > 0) { + if (patternStart.matcher(line).matches()) + { + if (input.length() > 0) + { input.delete(0, input.length()); } log = true; } - if (log) { + if (log) + { input.append(line).append("\n"); } - if (patternEnd.matcher(line).matches()) { + if (patternEnd.matcher(line).matches()) + { log = false; } } - if (input.length()>10000) { - input.delete(0, input.length()-10000); + if (input.length() > 10000) + { + input.delete(0, input.length() - 10000); } final PastieUpload pastie = new PastieUpload(); final String url = pastie.send(input.toString()); - final Channel channel = (Channel)connection.getClientState().getChannels().nextElement(); String message = "Startup: " + url; - chatUser.sendMessage("§6" + connection.getClientState().getNick().getNick() + ": §7" + message); - connection.sendCommand(new MessageCommand(channel.getName(), message)); + chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message); + ircBot.sendMessage(message); } catch (IOException ex) { @@ -455,10 +428,9 @@ public class EssentialsHelp extends PlayerListener } final PastieUpload pastie = new PastieUpload(); final String url = pastie.send(input.toString()); - final Channel channel = (Channel)connection.getClientState().getChannels().nextElement(); String message = "Essentials config.yml: " + url; - chatUser.sendMessage("§6" + connection.getClientState().getNick().getNick() + ": §7" + message); - connection.sendCommand(new MessageCommand(channel.getName(), message)); + chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message); + ircBot.sendMessage(message); } catch (IOException ex) @@ -487,8 +459,8 @@ public class EssentialsHelp extends PlayerListener { if (event.getPlayer() == chatUser) { - sendChatMessage(event.getPlayer(), event.getMessage()); - event.setCancelled(true); + boolean success = sendChatMessage(event.getPlayer(), event.getMessage()); + event.setCancelled(success); return; } } @@ -497,105 +469,10 @@ public class EssentialsHelp extends PlayerListener public void onPlayerQuit(PlayerQuitEvent event) { chatUser = null; - if (autoReconnect != null) - { - autoReconnect.disable(); - } - shouldQuit = true; - if (connection != null) - { - connection.sendCommand(new QuitCommand("Connection closed by user.")); + if (ircBot != null) { + ircBot.quit(); + ircBot = null; } return; } - - - class KickAutoJoin extends AutoJoin - { - private String channel; - - public KickAutoJoin(IRCConnection connection, String channel) - { - super(connection, channel); - this.channel = channel; - } - - @Override - protected void updateCommand(InCommand command_o) - { - if (command_o instanceof KickCommand) - { - final KickCommand kickCommand = (KickCommand)command_o; - - if (kickCommand.kickedUs(getConnection().getClientState())) - { - if (Channel.areEqual(kickCommand.getChannel(), channel)) - { - chatUser.sendMessage("You have been kicked from the channel: " + kickCommand.getComment()); - chatUser = null; - autoReconnect.disable(); - shouldQuit = true; - connection.sendCommand(new QuitCommand("Connection closed by user.")); - } - } - } - else if (command_o instanceof GenericJoinError) - { - GenericJoinError joinErr = (GenericJoinError)command_o; - - if (Channel.areEqual(joinErr.getChannel(), channel)) - { - scheduleJoin(); - } - } - else if (command_o instanceof InviteCommand) - { - InviteCommand invite = (InviteCommand)command_o; - if (!getConnection().getClientState().isOnChannel(invite.getChannel())) - { - performJoin(); - } - } - } - } - - - class IRCListener extends GenericAutoService - { - public IRCListener(final IRCConnection connection) - { - super(connection); - enable(); - } - - @Override - protected void updateState(final State state) - { - if (state == State.UNCONNECTED && shouldQuit) - { - connection = null; - shouldQuit = false; - } - } - - @Override - protected void updateCommand(final InCommand command) - { - if (command instanceof MessageCommand) - { - final MessageCommand msg = (MessageCommand)command; - EssentialsHelp.this.handleIRCmessage(msg.getSource().getNick(), msg.getMessage()); - } - if (command instanceof TopicCommand) - { - final TopicCommand msg = (TopicCommand)command; - EssentialsHelp.this.handleIRCmessage(msg.getChannel(), msg.getTopic()); - } - if (command instanceof NoticeCommand) - { - final NoticeCommand msg = (NoticeCommand)command; - EssentialsHelp.this.handleIRCmessage(msg.getFrom().getNick(), msg.getNotice()); - } - } - } } diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/IrcBot.java b/EssentialsUpdate/src/com/earth2me/essentials/update/IrcBot.java new file mode 100644 index 000000000..ce6205474 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/IrcBot.java @@ -0,0 +1,163 @@ +package com.earth2me.essentials.update; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.logging.Level; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.jibble.pircbot.Colors; +import org.jibble.pircbot.IrcException; +import org.jibble.pircbot.PircBot; +import org.jibble.pircbot.User; + + +public class IrcBot extends PircBot +{ + private static final String channel = "#essentials"; + private static final int port = 6667; + private static final String server = "irc.esper.net"; + private transient boolean reconnect = true; + private transient Player player; + private transient boolean kicked = false; + + public IrcBot(Player player, final String nickName, final String versionString) + { + this.player = player; + setName(nickName); + setLogin("esshelp"); + setVersion(versionString); + connect(); + joinChannel(channel); + } + + private void connect() + { + try + { + connect(server, port); + return; + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); + } + catch (IrcException ex) + { + Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); + } + + } + + public void quit() + { + reconnect = false; + disconnect(); + } + + @Override + protected void onConnect() + { + reconnect = true; + } + + @Override + protected void onDisconnect() + { + super.onDisconnect(); + if (reconnect) + { + connect(); + } + } + + @Override + protected void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) + { + if (recipientNick.equals(getNick())) + { + player.sendMessage("You have been kicked from the channel: " + reason); + quit(); + kicked = true; + } + } + + public boolean isKicked() + { + return kicked; + } + + @Override + protected void onMessage(String channel, String sender, String login, String hostname, String message) + { + player.sendMessage(formatChatMessage(sender, message, false)); + } + + @Override + protected void onAction(String sender, String login, String hostname, String target, String action) + { + player.sendMessage(formatChatMessage(sender, action, true)); + } + + @Override + protected void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice) + { + player.sendMessage(formatChatMessage(sourceNick, notice, false)); + } + + @Override + protected void onTopic(String channel, String topic, String setBy, long date, boolean changed) + { + player.sendMessage(formatChatMessage(channel, topic, false)); + } + + public String formatChatMessage(String nick, String message, boolean action) + { + final StringBuilder sb = new StringBuilder(); + sb.append("§6"); + if (action) + { + sb.append('*'); + } + sb.append(nick); + if (!action) + { + sb.append(':'); + } + sb.append(" §7"); + sb.append(replaceColors(message)); + return sb.toString(); + } + + private String replaceColors(String message) + { + String m = Colors.removeFormatting(message); + m = m.replaceAll("\u000310(,(0?[0-9]|1[0-5]))?", "§b"); + m = m.replaceAll("\u000311(,(0?[0-9]|1[0-5]))?", "§f"); + m = m.replaceAll("\u000312(,(0?[0-9]|1[0-5]))?", "§9"); + m = m.replaceAll("\u000313(,(0?[0-9]|1[0-5]))?", "§d"); + m = m.replaceAll("\u000314(,(0?[0-9]|1[0-5]))?", "§8"); + m = m.replaceAll("\u000315(,(0?[0-9]|1[0-5]))?", "§7"); + m = m.replaceAll("\u00030?1(,(0?[0-9]|1[0-5]))?", "§0"); + m = m.replaceAll("\u00030?2(,(0?[0-9]|1[0-5]))?", "§1"); + m = m.replaceAll("\u00030?3(,(0?[0-9]|1[0-5]))?", "§2"); + m = m.replaceAll("\u00030?4(,(0?[0-9]|1[0-5]))?", "§c"); + m = m.replaceAll("\u00030?5(,(0?[0-9]|1[0-5]))?", "§4"); + m = m.replaceAll("\u00030?6(,(0?[0-9]|1[0-5]))?", "§5"); + m = m.replaceAll("\u00030?7(,(0?[0-9]|1[0-5]))?", "§6"); + m = m.replaceAll("\u00030?8(,(0?[0-9]|1[0-5]))?", "§e"); + m = m.replaceAll("\u00030?9(,(0?[0-9]|1[0-5]))?", "§a"); + m = m.replaceAll("\u00030?0(,(0?[0-9]|1[0-5]))?", "§f"); + m = Colors.removeColors(m); + return m; + } + + public void sendMessage(String message) + { + sendMessage(channel, message); + } + + public User[] getUsers() + { + return getUsers(channel); + } +} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/ClientStateMonitor.java b/EssentialsUpdate/src/f00f/net/irc/martyr/ClientStateMonitor.java deleted file mode 100644 index 0b7303956..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/ClientStateMonitor.java +++ /dev/null @@ -1,67 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.Observable; -import java.util.Observer; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * ClientStateMonitor asks commands to update the client state. - */ -public class ClientStateMonitor implements Observer -{ - - static Logger log = Logger.getLogger(ClientStateMonitor.class.getName()); - - private IRCConnection connection; - - private boolean enabled = false; - - /** - * This should only be called by the IRCConnection itself. - * - * @param connection Connection we are associated with - */ - ClientStateMonitor( IRCConnection connection ) - { - this.connection = connection; - - enable(); - } - - public void enable() - { - if( enabled ) - return; - enabled = true; - - connection.addCommandObserver( this ); - } - - public void disable() - { - if( !enabled ) - return; - connection.removeCommandObserver( this ); - enabled = false; - } - - public void update( Observable observable, Object command_o ) - { - InCommand command = (InCommand)command_o; - - try - { - /*if( */command.updateClientState( connection.getClientState() );// ) - //log.debug("ClientStateMonnitor: Client state updated"); - } - catch( Throwable e ) - { - log.log(Level.SEVERE,"ClientStateMonitor: Client state update failed.", e); - } - - } - - // ===== END ClientStateMonitor -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/Command.java b/EssentialsUpdate/src/f00f/net/irc/martyr/Command.java deleted file mode 100644 index ff8f168cd..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/Command.java +++ /dev/null @@ -1,18 +0,0 @@ -package f00f.net.irc.martyr; - -/** - * Defines an object which is a command, either incoming or outgoing. - */ -public interface Command -{ - /** - * Returns the string IRC uses to identify this command. Examples: - * NICK, PING, KILL, 332. Not strictly required for OutCommands - * as the irc identifier is expected to be part of the reder() - * result. - * - * @return The IRC identifier string - */ - String getIrcIdentifier(); -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandObserver.java b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandObserver.java deleted file mode 100644 index 5f988c0c3..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandObserver.java +++ /dev/null @@ -1,5 +0,0 @@ -package f00f.net.irc.martyr; - -public class CommandObserver extends StateObserver -{ -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandRegister.java b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandRegister.java deleted file mode 100644 index 2c7dca1dc..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandRegister.java +++ /dev/null @@ -1,118 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.Hashtable; - -import f00f.net.irc.martyr.commands.*; -import f00f.net.irc.martyr.errors.*; -import f00f.net.irc.martyr.replies.*; - -/** - * CommandRegister is basically a big hashtable that maps IRC - * identifiers to command objects that can be used as factories to - * do self-parsing. CommandRegister is also the central list of - * commands. - */ -public class CommandRegister -{ - - private Hashtable commands; - public CommandRegister() - { - commands = new Hashtable(); - - // Note that currently, we only have to register commands that - // can be received from the server. - new InviteCommand().selfRegister( this ); - new JoinCommand().selfRegister( this ); - new KickCommand().selfRegister( this ); - new MessageCommand().selfRegister( this ); - new ModeCommand().selfRegister( this ); - new IsonCommand().selfRegister( this ); - new NickCommand().selfRegister( this ); - new NoticeCommand().selfRegister( this ); - new PartCommand().selfRegister( this ); - new PingCommand().selfRegister( this ); - new QuitCommand().selfRegister( this ); - new TopicCommand().selfRegister( this ); - new WelcomeCommand().selfRegister( this ); - - // Register errors - new AlreadyRegisteredError().selfRegister( this ); - new CannotSendToChanError().selfRegister( this ); - new CantKillServerError().selfRegister( this ); - new ChannelBannedError().selfRegister( this ); - new ChannelInviteOnlyError().selfRegister( this ); - new ChannelLimitError().selfRegister( this ); - new ChannelWrongKeyError().selfRegister( this ); - new ChanOPrivsNeededError().selfRegister( this ); - new ErroneusNicknameError().selfRegister( this ); - new FileErrorError().selfRegister( this ); - new KeySetError().selfRegister( this ); - new LoadTooHighError().selfRegister( this ); - new NeedMoreParamsError().selfRegister( this ); - new NickCollisionError().selfRegister( this ); - new NickInUseError().selfRegister( this ); - new NoAdminInfoError().selfRegister( this ); - new NoLoginError().selfRegister( this ); - new NoMotdError().selfRegister( this ); - new NoNicknameGivenError().selfRegister( this ); - new NoOperHostError().selfRegister( this ); - new NoOriginError().selfRegister( this ); - new NoPermForHostError().selfRegister( this ); - new NoPrivilegesError().selfRegister( this ); - new NoRecipientError().selfRegister( this ); - new NoSuchChannelError().selfRegister( this ); - new NoSuchNickError().selfRegister( this ); - new NoSuchServerError().selfRegister( this ); - new NoTextToSendError().selfRegister( this ); - new NotOnChannelError().selfRegister( this ); - new NotRegisteredError().selfRegister( this ); - new PasswdMismatchError().selfRegister( this ); - new SummonDisabledError().selfRegister( this ); - new TooManyChannelsError().selfRegister( this ); - new TooManyTargetsError().selfRegister( this ); - new UModeUnknownFlagError().selfRegister( this ); - new UnknownCommandError().selfRegister( this ); - new UnknownModeError().selfRegister( this ); - new UserNotInChannelError().selfRegister( this ); - new UserOnChannelError().selfRegister( this ); - new UsersDisabledError().selfRegister( this ); - new UsersDontMatchError().selfRegister( this ); - new WasNoSuchNickError().selfRegister( this ); - new WildTopLevelError().selfRegister( this ); - new YoureBannedCreepError().selfRegister( this ); - - // Register replies - new ChannelCreationReply().selfRegister( this ); - new AwayReply().selfRegister( this ); - new ListEndReply().selfRegister( this ); - new ListReply().selfRegister( this ); - new ListStartReply().selfRegister( this ); - new LUserClientReply().selfRegister( this ); - new LUserMeReply().selfRegister( this ); - new LUserOpReply().selfRegister( this ); - new ModeReply().selfRegister( this ); - new NamesEndReply().selfRegister( this ); - new NamesReply().selfRegister( this ); - new NowAwayReply().selfRegister( this ); - new TopicInfoReply().selfRegister( this ); - new UnAwayReply().selfRegister( this ); - new WhoisChannelsReply().selfRegister( this ); - new WhoisEndReply().selfRegister( this ); - new WhoisIdleReply().selfRegister( this ); - new WhoisServerReply().selfRegister( this ); - new WhoisUserReply().selfRegister( this ); - } - - public void addCommand( String ident, InCommand command ) - { - commands.put( ident, command ); - } - - public InCommand getCommand( String ident ) - { - return commands.get( ident ); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandSender.java b/EssentialsUpdate/src/f00f/net/irc/martyr/CommandSender.java deleted file mode 100644 index a5a748e86..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/CommandSender.java +++ /dev/null @@ -1,14 +0,0 @@ -package f00f.net.irc.martyr; - -/** - * A CommandSender can accept an OutCommand and do something with it - * (such as send it to the server, or send it on to another - * CommandSender). The idea is to create a chain of CommandSenders, - * with the last object in the chain the default CommandSender, - * created by IRCConnection. - * */ -public interface CommandSender -{ - CommandSender getNextCommandSender(); - void sendCommand( OutCommand command ); -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/CronManager.java b/EssentialsUpdate/src/f00f/net/irc/martyr/CronManager.java deleted file mode 100644 index 3c5d8b196..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/CronManager.java +++ /dev/null @@ -1,80 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.Date; -import java.util.Timer; -import java.util.TimerTask; - -/** - * @since 0.3.2 - * */ -public class CronManager -{ - private Timer timer; - - public CronManager() - { - timer = new Timer(); - } - - /** - * @param task TimerTask to schedule - * @param time When to schedule task - */ - public void schedule(TimerTask task, Date time) - { - timer.schedule(task, time); - } - - /** - * @param task TimerTask to schedule - * @param firstTime When to run first - * @param period How often to run - */ - public void schedule(TimerTask task, Date firstTime, long period) - { - timer.schedule(task, firstTime, period); - } - - /** - * @param task TimerTask to schedule - * @param delay How long to wait before running - */ - public void schedule(TimerTask task, long delay) - { - timer.schedule(task, delay); - } - - /** - * @param task TimerTask to schedule - * @param delay How long to wait before running - * @param period How often to run - */ - public void schedule(TimerTask task, long delay, long period) - { - timer.schedule(task, delay, period); - } - - /** - * @param task TimerTask to schedule - * @param firstTime When first to run - * @param period How often to run - */ - public void scheduleAtFixedRate( - TimerTask task, - Date firstTime, - long period) - { - timer.scheduleAtFixedRate(task, firstTime, period); - } - - /** - * @param task TimerTask to schedule - * @param delay When first to run - * @param period How often to run - */ - public void scheduleAtFixedRate(TimerTask task, long delay, long period) - { - timer.scheduleAtFixedRate(task, delay, period); - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/ForwardObservable.java b/EssentialsUpdate/src/f00f/net/irc/martyr/ForwardObservable.java deleted file mode 100644 index 7f4d8d89a..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/ForwardObservable.java +++ /dev/null @@ -1,66 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.Observer; -import java.util.Observable; -import java.util.LinkedList; -import java.util.List; - -/** - * Does notifications in the order they are added. - * */ -public class ForwardObservable extends Observable -{ - private boolean changed = true; - private List obs = new LinkedList(); - private final Object localMonitor = new Object(); - - - public void setChanged() - { - synchronized(localMonitor) - { - changed = true; - } - } - - protected void clearChanged() - { - synchronized(localMonitor) - { - changed = false; - } - } - - public void addObserver( Observer o ) - { - synchronized(localMonitor) - { - obs.add( o ); - } - } - - public void deleteObserver( Observer o ) - { - synchronized(localMonitor) - { - obs.remove( o ); - } - } - - public void notifyObservers(Object arg) - { - synchronized(localMonitor) - { - if (!changed) - return; - clearChanged(); - - for (Observer ob : obs) { - ob.update(this, arg); - } - } - } - - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/GenericAutoService.java b/EssentialsUpdate/src/f00f/net/irc/martyr/GenericAutoService.java deleted file mode 100644 index 0b3546231..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/GenericAutoService.java +++ /dev/null @@ -1,54 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.Observable; - -/** - * Provides a framework for an auto service. Does enable by default. - * Splits the 'update' method into two, 'updateState' and 'updateCommand'. - * Also provides thread safety on all methods. - */ -public abstract class GenericAutoService extends GenericCommandAutoService -{ - -protected GenericAutoService( IRCConnection connection ) -{ - super( connection ); -} - -public synchronized void enable() -{ - if( enabled ) - return; - - connection.addStateObserver( this ); - - super.enable(); -} - -public synchronized void disable() -{ - if( !enabled ) - return; - - connection.removeStateObserver( this ); - - super.disable(); -} - -public synchronized void update( Observable observer, Object updated ) -{ - if( !enabled ) - throw new IllegalStateException("This observer is not enabled." ); - if( updated instanceof State ) - updateState( (State)updated ); - else - super.update( observer, updated ); -} - -protected abstract void updateState( State state ); - -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/GenericCommandAutoService.java b/EssentialsUpdate/src/f00f/net/irc/martyr/GenericCommandAutoService.java deleted file mode 100644 index b9c1d5ede..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/GenericCommandAutoService.java +++ /dev/null @@ -1,79 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.Observable; -import java.util.Observer; - -/** - * Provides a framework for an auto service that operates with - * InCommands. Does enable by default. Splits the 'update' method - * into two, 'updateState' and 'updateCommand'. Also provides thread - * safety on all methods. - */ -public abstract class GenericCommandAutoService implements Observer -{ - -protected boolean enabled = false; -protected IRCConnection connection; - -protected GenericCommandAutoService( IRCConnection connection ) -{ - this.connection = connection; - - enable(); -} - -public synchronized void enable() -{ - if( enabled ) - return; - - connection.addCommandObserver( this ); - enabled = true; -} - -public synchronized void disable() -{ - if( !enabled ) - return; - - connection.removeCommandObserver( this ); - enabled = false; -} - -public synchronized void update( Observable observer, Object updated ) -{ - if( !enabled ) - throw new IllegalStateException("This observer is not enabled." ); - if( updated instanceof State ) - { - throw new IllegalArgumentException("This is not a state observer." ); - } - else if( updated instanceof InCommand ) - { - updateCommand( (InCommand)updated ); - } - else - { - throw new IllegalArgumentException("Unknown object given to update."); - } -} - -protected IRCConnection getConnection() -{ - return connection; -} - -protected synchronized boolean isEnabled() -{ - return enabled; -} - -protected abstract void updateCommand( InCommand command ); - - -// END AutoRegister -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/IRCConnection.java b/EssentialsUpdate/src/f00f/net/irc/martyr/IRCConnection.java deleted file mode 100644 index 159f533cd..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/IRCConnection.java +++ /dev/null @@ -1,1163 +0,0 @@ -/* - * IRCConnection.java - * - * Copyright (C) 2000, 2001, 2002, 2003, 2004 Ben Damm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * See: http://www.fsf.org/copyleft/lesser.txt - */ - -package f00f.net.irc.martyr; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.net.InetAddress; -import java.net.Socket; -import java.util.LinkedList; -import java.util.Observer; -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.commands.UnknownCommand; -import f00f.net.irc.martyr.errors.UnknownError; -import f00f.net.irc.martyr.replies.UnknownReply; -import java.util.logging.Level; -import java.util.logging.Logger; - -// TODO: -// -// Add synchronous disconnect. -// -/** - *

IRCConnection is the core class for Martyr. - * IRCConnection manages the socket, giving commands to the server - * and passing results to the parse engine. It manages passing information out - * to the application via the command listeners and state listeners. - * IRCConnection has no IRC intelligence of its own, that is left - * up to the classes on the command and state listener lists. A number of - * listeners that do various tasks are provided as part of the framework.

- * - *

Please read this entirely before using the framework. Or - * what the heck, try out the example below and see if it works for ya.

- * - *

States and State Listeners

- *

IRCConnection is always in one of three states. - * UNCONNECTED, UNREGISTERED or - * REGISTERED. It keeps a list of listeners that - * would like to know when a state change occurs. When a state change - * occurs each listener in the list, in the order they were added, is - * notified. If a listener early up on the list causes something to happen - * that changes the state before your listener gets notified, you will be - * notified of the state change even though the state has changed. You - * will be notified again of the new state. That is, state change - * notifications will always be in order, but they may not always reflect - * the "current" state.

- * - *

Commands and Command Listeners

- *

IRCConnection also keeps a list of listeners for - * when a command arrives from the server. When a command arrives, it - * is first parsed into an object. That object is then passed around - * to all the listeners, again, in order. Commands can be received - * and the socket closed before the commands are actually send to the - * listeners, so beware that even though you receive a command, you - * may not always be guaranteed to have an open socket to send a - * response back on. A consumer of the command should never modify - * the command object. If you try to send a command to a closed - * socket, IRCConnection will silently ignore your - * command. Commands should always be received in order by all - * listeners, even if a listener higher up in the list sends a - * response to the server which elicits a response back from the - * server before you've been told of the first command.

- * - *

Connecting and staying connected

- *

The AutoReconnect class can connect you and will try to stay - * connected. Using AutoReconnect to connect the - * first time is recommended, use the go(server,port) method once - * you are ready to start.

- * - *

Registration On The Network

- *

The AutoRegister class can register you automatically on the - * network. Otherwise, registration is left up to the consumer. - * Registration should occur any time the state changes to - * UNREGISTERED. The consumer will know this because it - * has registered some class as a state observer. - *

- * - *

Auto Response

- *

Some commands, such as Ping require an automatic response. - * Commands that fall into this category can be handled by the - * AutoResponder class. For a list of what commands - * AutoResponder auto responds to, see the source.

- * - *

Joining and Staying Joined

- *

You can use the AutoJoin class to join a channel - * and stay there. AutoJoin will try to re-join if - * kicked or if the connection is lost and the server re-connects. - * AutoJoin can be used any time a join is desired. If - * the server is not connected, it will wait until the server - * connects. If the server is connected, it will try to join right - * away.

- * - *

Example Usage

- *

You will probably want to at least use the - * AutoRegister and AutoResponder classes. - * Example:

- * - *

Note that in the example, the first line is optional. - * IRCConnection can be called with its default - * constructor. See note below about why this is done. - * IRCConnection will instantiate its own - * ClientState object if you do not provide one.

- * - *
- * ClientState clientState = new MyAppClientState();
- * IRCConnection connection = new IRCConnection( clientState );
- *
- * // AutoRegister and AutoResponder both add themselves to the
- * // appropriate observerables.  Both will remove themselves with the
- * // disable() method.
- * 
- * AutoRegister autoReg
- *   = new AutoRegister( "repp", "bdamm", "Ben Damm", connection );
- * AutoReconnect autoRecon = new AutoReconnect( connection );
- * AutoResponder autoRes = new AutoResponder( connection );
- *
- * // Very important that the objects above get added before the connect.
- * // If done otherwise, AutoRegister will throw an
- * // IllegalStateException, as AutoRegister can't catch the
- * // state switch to UNREGISTERED from UNCONNECTED.
- *
- * autoRecon.go( server, port );
- * 
- * - *

Client State

- *

The ClientStateMonitor class tells commands to - * change the client state when they are received. - * ClientStateMonitor is automatically added to the - * command queue before any other command, so that you can be - * guaranteed that the ClientState is updated before any - * observer sees a command.

- * - *

So, how does an application know when a channel has been joined, - * a user has joined a channel we are already on, etc? How does the - * application get fine-grained access to client state change info? - * This is a tricky question, and the current solution is to sublcass - * the clientstate.ClientState and - * clientstate.Channel classes with your own, overriding - * the setXxxxXxxx methods. Each method would call - * super.setXxxXxxx and then proceed to change the - * application as required.

- * - *

Startup

- *

IRCConnection starts in the UNCONNECTED state and - * makes no attempt to connect until the connect(...) - * method is called.

- * - *

IRCConnection starts a single thread at - * construction time. This thread simply waits for events. An event - * is a disconnection request or an incoming message. Events are - * dealt with by this thread. If connect is called, a second thread - * is created to listen for input from the server (InputHandler). - * - * @see f00f.net.irc.martyr.A_FAQ - * @see f00f.net.irc.martyr.clientstate.ClientState - * @see f00f.net.irc.martyr.services.AutoRegister - * @see f00f.net.irc.martyr.services.AutoResponder - * @see f00f.net.irc.martyr.State - * - */ -/* - * Event handling re-org - * - * - A message is an event - * - A disconnect request is an event, placed on the queue? - * -- Off I go to do other stuff. - */ -public class IRCConnection { - static Logger log = Logger.getLogger(IRCConnection.class.getName()); - - public IRCConnection() - { - this( new ClientState() ); - } - - public IRCConnection( ClientState clientState ) - { - // State observers are notified of state changes. - // Command observers are sent a copy of each message that arrives. - stateObservers = new StateObserver(); - commandObservers = new CommandObserver(); - this.clientState = clientState; - stateQueue = new LinkedList(); - - commandRegister = new CommandRegister(); - commandSender = new DefaultCommandSender(); - - setState( State.UNCONNECTED ); - - new ClientStateMonitor( this ); - - localEventQueue = new LinkedList(); - - eventThread = new EventThread(); - eventThread.setDaemon( true ); - startEventThread(); - } - - /** - * This method exists so that subclasses may perform operations before - * the event thread starts, but overriding this method. - * */ - protected void startEventThread() - { - eventThread.start(); - } - - /** - * In the event you want to stop martyr, call this. This asks the - * event thread to finish the current event, then die. - * */ - public void stop() - { - eventThread.doStop(); - } - - /** - * Performs a standard connection to the server and port. If we are already - * connected, this just returns. - * - * @param server Server to connect to - * @param port Port to connect to - * @throws IOException if we could not connect - */ - public void connect( String server, int port ) - throws IOException - { - synchronized( connectMonitor ) - { - //log.debug("IRCConnection: Connecting to " + server + ":" + port); - if( connected ) - { - log.severe("IRCConnection: Connect requested, but we are already connected!"); - return; - } - - connectUnsafe( new Socket( server, port ), server ); - } - } - - /** - * This allows the developer to provide a pre-connected socket, ready for use. - * This is so that any options that the developer wants to set on the socket - * can be set. The server parameter is passed in, rather than using the - * customSocket.getInetAddr() because a DNS lookup may be undesirable. Thus, - * the canonical server name, whatever that is, should be provided. This is - * then passed on to the client state. - * - * @param customSocket Custom socket that we will connect over - * @param server Server to connect to - * @throws IOException if we could not connect - * @throws IllegalStateException if we are already connected. - */ - public void connect( Socket customSocket, String server ) - throws IOException, IllegalStateException - { - synchronized( connectMonitor ) - { - if( connected ) - { - throw new IllegalStateException( "Connect requested, but we are already connected!" ); - } - - connectUnsafe( customSocket, server ); - } - - } - - /** - *

Orders the socket to disconnect. This doesn't actually disconnect, it - * merely schedules an event to disconnect. This way, pending incoming - * messages may be processed before a disconnect actually occurs.

- *

No errors are possible from the disconnect. If you try to disconnect an - * unconnected socket, your disconnect request will be silently ignored.

- */ - public void disconnect() - { - synchronized( eventMonitor ) - { - disconnectPending = true; - eventMonitor.notifyAll(); - } - } - - /** - * Sets the daemon status on the threads that IRCConnection - * creates. Default is true, that is, new InputHandler threads are - * daemon threads, although the event thread is always a daemon. The - * result is that as long as there is an active connection, the - * program will keep running. - * - * @param daemon Set if we are to be treated like a daemon - */ - public void setDaemon( boolean daemon ) - { - this.daemon = daemon; - } - - /** - * Signal threads to stop, and wait for them to do so. - * @param timeout *2 msec to wait at most for stop. - * - * */ - public void shutdown(long timeout) - { - // Note: UNTESTED! - try - { - // 1) shut down the input thread. - synchronized( inputHandlerMonitor ) - { - if( inputHandler != null ) - { - inputHandler.signalShutdown(); - } - synchronized( socketMonitor ) - { - if( socket != null ) - { - try - { - socket.close(); - } - catch (IOException e) - { - // surprising? - } - } - } - if( inputHandler != null ) - { - inputHandler.join(timeout); - } - } - - // 2) shut down the event thread. - eventThread.shutdown(); - eventThread.join(timeout); - } - catch( InterruptedException ie ) - { - // We got interrupted - while waiting for death. - // Shame that. - } - } - - public String toString() - { - return "IRCConnection"; - } - - public void addStateObserver( Observer observer ) - { - //log.debug("IRCConnection: Added state observer " + observer); - stateObservers.addObserver( observer ); - } - - public void removeStateObserver( Observer observer ) - { - //log.debug("IRCConnection: Removed state observer " + observer); - stateObservers.deleteObserver( observer ); - } - - public void addCommandObserver( Observer observer ) - { - //log.debug("IRCConnection: Added command observer " + observer); - commandObservers.addObserver( observer ); - } - - public void removeCommandObserver( Observer observer ) - { - //log.debug("IRCConnection: Removed command observer " + observer); - commandObservers.deleteObserver( observer ); - } - - - public State getState() - { - return state; - } - - public ClientState getClientState() - { - return clientState; - } - - /** - * Accepts a command to be sent. Sends the command to the - * CommandSender. - * - * @param command Command we will send - * */ - public void sendCommand( OutCommand command ) - { - commandSender.sendCommand( command ); - } - - /** - * @return the first class in a chain of OutCommandProcessors. - * */ - public CommandSender getCommandSender() - { - return commandSender; - } - - /** - * @param sender sets the class that is responsible for sending commands. - * */ - public void setCommandSender( CommandSender sender ) - { - this.commandSender = sender; - } - - /** - * @return the local address to which the socket is bound. - * */ - public InetAddress getLocalAddress() - { - return socket.getLocalAddress(); - } - - public String getRemotehost() - { - return clientState.getServer(); - } - - /** - * Sets the time in milliseconds we wait after each command is sent. - * - * @param sleepTime Length of time to sleep between commands - * */ - public void setSendDelay( int sleepTime ) - { - this.sendDelay = sleepTime; - } - - /** - * @since 0.3.2 - * @return a class that can schedule timer tasks. - * */ - public CronManager getCronManager() - { - if( cronManager == null ) - cronManager = new CronManager(); - return cronManager; - } - - /** - * Inserts into the event queue a command that was not directly - * received from the server. - * - * @param fakeCommand Fake command to inject into incoming queue - * */ - public void injectCommand( String fakeCommand ) - { - synchronized( eventMonitor ) - { - localEventQueue.add( fakeCommand ); - eventMonitor.notifyAll(); - } - } - - // ===== package methods ============================================= - - void socketError( IOException ioe ) - { - //log.debug("Socket error called."); - //log.debug("IRCConnection: The stack of the exception:", ioe); - - //log.log(Level.SEVERE, "Socket error", ioe); - disconnect(); - } - - /** - * Splits a raw IRC command into three parts, the prefix, identifier, - * and parameters. - * @param wholeString String to be parsed - * @return a String array with 3 components, {prefix,ident,params}. - * */ - public static String[] parseRawString( String wholeString ) - { - String prefix = ""; - String identifier; - String params = ""; - - StringTokenizer tokens = new StringTokenizer( wholeString, " " ); - - if( wholeString.charAt(0) == ':' ) - { - prefix = tokens.nextToken(); - prefix = prefix.substring( 1, prefix.length() ); - } - - identifier = tokens.nextToken(); - - if( tokens.hasMoreTokens() ) - { - // The rest of the string - params = tokens.nextToken(""); - } - - String[] result = new String[3]; - result[0] = prefix; - result[1] = identifier; - result[2] = params; - - return result; - } - - /** - * Given the three parts of an IRC command, generates an object to - * represent that command. - * - * @param prefix Prefix of command object - * @param identifier ID of command - * @param params Params of command - * @return An InCommand object for the given command object - * */ - protected InCommand getCommandObject( String prefix, String identifier, String params ) - { - InCommand command; - - // Remember that commands are also factories. - InCommand commandFactory = commandRegister.getCommand( identifier ); - if( commandFactory == null ) - { - if( UnknownError.isError( identifier ) ) - { - command = new UnknownError( identifier ); - log.warning("IRCConnection: Using " + command); - } - else if( UnknownReply.isReply( identifier ) ) - { - command = new UnknownReply( identifier ); - //log.warning("IRCConnection: Using " + command); - } - else - { - // The identifier doesn't map to a command. - log.warning("IRCConnection: Unknown command"); - command = new UnknownCommand(); - } - } - else - { - command = commandFactory.parse( prefix, identifier, params); - - if( command == null ) - { - log.severe("IRCConnection: CommandFactory[" + commandFactory + "] returned NULL"); - return null; - } - //log.debug("IRCConnection: Using " + command); - } - - return command; - } - - - - /** - * Executed by the event thread. - * - * @param wholeString String to be parsed and handled - * */ - void incomingCommand( String wholeString ) - { - //log.info("IRCConnection: RCV = " + wholeString); - - // 1) Parse out the command - String cmdBits[]; - - try - { - cmdBits = parseRawString( wholeString ); - } - catch( Exception e ) - { - // So.. we can't process the command. - // So we call the error handler. - handleUnparsableCommand( wholeString, e ); - return; - } - - String prefix = cmdBits[0]; - String identifier = cmdBits[1]; - String params = cmdBits[2]; - - // 2) Fetch command from factory - InCommand command = getCommandObject( prefix, identifier, params ); - command.setSourceString( wholeString ); - - // Update the state and send out to commandObservers - localCommandUpdate( command ); - } - - protected void handleUnparsableCommand( String wholeString, Exception e ) - { - log.log(Level.SEVERE, "Unable to parse server message.", e ); - } - - /** - * Called only in the event thread. - * - * @param command Command to update - * */ - private void localCommandUpdate( InCommand command ) - { - // 3) Change the connection state if required - // This allows us to change from UNREGISTERED to REGISTERED and - // possibly back. - State cmdState = command.getState(); - if( cmdState != State.UNKNOWN && cmdState != getState() ) - setState( cmdState ); - - // TODO: Bug here? - - // 4) Notify command observers - try - { - commandObservers.setChanged(); - commandObservers.notifyObservers( command ); - } - catch( Throwable e ) - { - log.log(Level.SEVERE, "IRCConnection: Command notify failed.", e); - } - - } - - // ===== private variables =========================================== - - /** Object used to send commands. */ - private CommandSender commandSender; - - private CronManager cronManager; - - /** State of the session. */ - private State state; - - /** - * Client state (our name, nick, groups, etc). Stored here mainly - * because there isn't anywhere else to stick it. - */ - private ClientState clientState; - - /** - * Maintains a list of classes observing the state and notifies them - * when it changes. - */ - private StateObserver stateObservers; - - /** - * Maintains a list of classes observing commands when they come in. - */ - private CommandObserver commandObservers; - - /** - * The actual socket used for communication. - */ - private Socket socket; - - /** - * Monitor access to socket. - * */ - private final Object socketMonitor = new Object(); - - /** - * We want to prevent connecting and disconnecting at the same time. - */ - private final Object connectMonitor = new Object(); - - /** - * This object should be notified if we want the main thread to check for - * events. An event is either an incoming message or a disconnect request. - * Sending commands to the server is synchronized by the eventMonitor. - */ - private final Object eventMonitor = new Object(); - - /** - * This tells the processEvents() method to check if we should disconnect - * after processing all incoming messages. - */ - // Protected by: - // inputHandlerMonitor - // eventMonitor - // connectMonitor - private boolean disconnectPending = false; - - /** - * The writer to use for output. - */ - private BufferedWriter socketWriter; - - /** - * Command register, contains a list of commands that can be received - * by the server and have matching Command objects. - */ - private CommandRegister commandRegister; - - /** - * Maintains a handle on the input handler. - */ - private InputHandler inputHandler; - - /** - * Access control for the input handler. - */ - private final Object inputHandlerMonitor = new Object(); - - /** - * State queue keeps a queue of requests to switch state. - */ - private LinkedList stateQueue; - - /** - * localEventQueue allows events not received from the server to be - * processed. - * */ - private LinkedList localEventQueue; - - /** - * Setting state prevents setState from recursing in an uncontrolled - * manner. - */ - private boolean settingState = false; - - /** - * Event thread waits for events and executes them. - */ - private EventThread eventThread; - - /** - * Determines the time to sleep every time we send a message. We do this - * so that the server doesn't boot us for flooding. - */ - private int sendDelay = 300; - - /** - * connected just keeps track of whether we are connected or not. - */ - private boolean connected = false; - - /** - * Are we set to be a daemon thread? - */ - private boolean daemon = false; - - // ===== private methods ============================================= - - /** - * Unsafe, because this method can only be called by a method that has a lock - * on connectMonitor. - * - * @param socket Socket to connect over - * @param server Server to connect to - * @throws IOException if connection fails - */ - private void connectUnsafe( Socket socket, String server ) - throws IOException - { - synchronized(socketMonitor) - { - this.socket = socket; - } - - socketWriter = - new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) ); - - /** - * The reader to use for input. Managed by the InputHandler. - */ - BufferedReader socketReader = - new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); - - // A simple thread that waits for input from the server and passes - // it off to the IRCConnection class. - //if( inputHandler != null ) - //{ - // log.fatal("IRCConnection: Non-null input handler on connect!!"); - // return; - //} - - synchronized( inputHandlerMonitor ) - { - // Pending events get processed after a disconnect call, and there - // shouldn't be any events generated while disconnected, so it makes - // sense to test for this condition. - if( inputHandler != null && inputHandler.pendingMessages() ) - { - log.severe("IRCConnection: Tried to connect, but there are pending messages!"); - return; - } - - if( inputHandler != null && inputHandler.isAlive() ) - { - log.severe("IRCConnection: Tried to connect, but the input handler is still alive!"); - return; - } - - clientState.setServer( server ); - clientState.setPort( socket.getPort() ); - - connected = true; - - inputHandler = new InputHandler( socketReader, this, eventMonitor ); - inputHandler.setDaemon( daemon ); - inputHandler.start(); - } - setState( State.UNREGISTERED ); - } - - private class EventThread extends Thread - { - private boolean doShutdown = false; - - public EventThread() - { - super("EventThread"); - } - - public void run() - { - handleEvents(); - } - - public void shutdown() - { - synchronized(eventMonitor) - { - this.doShutdown = true; - eventMonitor.notifyAll(); - } - } - - private void handleEvents() - { - try - { - while( true ) - { - // Process all events in the event queue. - //log.debug("IRCConnection: Processing events"); - while( processEvents() ) { } - - // We can't process events while synchronized on the - // eventMonitor because we may end up in deadlock. - synchronized( eventMonitor ) - { - if( !doShutdown && !pendingEvents() ) - { - eventMonitor.wait(); - } - - if( doShutdown ) - { - return; - } - } - } - } - catch( InterruptedException ie ) - { - log.log(Level.WARNING, "Interrupted while handling events.", ie ); - // And we do what? - // We die, that's what we do. - } - } - - public void doStop() - { - shutdown(); - } - - public String toString() - { - return "EventThread"; - } - } - - /** - * This method synchronizes on the inputHandlerMonitor. Note that if - * additional event types are processed, they also need to be added to - * pendingEvents(). - * @return true if events were processed, false if there were no events to - * process. - */ - private boolean processEvents() - { - boolean events = false; - - // the inputHandlerMonitor here serves two purposes: To protect - // from inputHandler changes and to ensure only one thread is - // operating in processEvents. - // - // Perhaps a different monitor should be used? - synchronized( inputHandlerMonitor ) - { - while( inputHandler != null && inputHandler.pendingMessages() ) - { - String msg = inputHandler.getMessage(); - incomingCommand( msg ); - events = true; - } - - while( localEventQueue != null && !localEventQueue.isEmpty() ) - { - String msg = localEventQueue.removeFirst(); - incomingCommand( msg ); - events = true; - } - - if( disconnectPending ) - { - //log.debug("IRCConnection: Process events: Disconnect pending."); - doDisconnect(); - events = true; - } - } - - return events; - } - - /** - * Does no synchronization on its own. This does not synchronize on - * any of the IRCConnection monitors or objects and returns after making a - * minimum of method calls. - * @return true if there are pending events that need processing. - */ - private boolean pendingEvents() - { - if( inputHandler != null && inputHandler.pendingMessages() ) - return true; - if( disconnectPending ) - return true; - if( localEventQueue != null && !localEventQueue.isEmpty() ) - return true; - - return false; - } - - // Synchronized by inputHandlerMonitor, called only from processEvents. - private void doDisconnect() - { - synchronized( connectMonitor ) - { - disconnectPending = false; - - if( !connected ) - { - return; - } - connected = false; - - try - { - final long startTime = System.currentTimeMillis(); - final long sleepTime = 1000; - final long stopTime = startTime + sleepTime; - //log.debug("IRCConnection: Sleeping for a bit (" - // + sleepTime + ").."); - // Slow things down a bit so the server doesn't kill us - // Also, we want to give a second to let any pending messages - // get processed and any pending disconnect() calls to be made. - // It is important that we use wait instead of sleep! - while( stopTime - System.currentTimeMillis() > 0 ) - { - connectMonitor.wait( stopTime - System.currentTimeMillis() ); - } - } - catch( InterruptedException ie ) - { - // Ignore - } - - //log.debug("IRCConnection: Stopping input handler."); - // Deprecated? - // inputHandler.stop(); - // inputHandler = null; - - //log.debug("IRCConnection: Closing socket."); - try - { - socket.close(); - } - catch( IOException ioe ) - { - // And we are supposed to do what? - // This probably means we've called disconnect on a closed - // socket. - handleSocketCloseException( ioe ); - return; - } - finally - { - connected = false; - } - } - - // The input handler should die, because we closed the socket. - // We'll wait for it to die. - synchronized( inputHandlerMonitor ) - { - //log.debug("IRCConnection: Waiting for the input handler to die.."); - try - { - // log.debug("IRCConnection: Stack:"); - - if( inputHandler.isAlive() ) - inputHandler.join(); - else - { - //log.debug("IRCConnection: No waiting required, input hander is already dead."); - } - } - catch( InterruptedException ie ) - { - //log.debug("IRCConnection: Error in join(): " + ie); - } - //log.debug("IRCConnection: Done waiting for the input handler to die."); - } - - - // There may be pending messages that we should process before we - // actually notify all the state listeners. - processEvents(); - - // It is important that the state be switched last. One of the - // state listeners may try to re-connect us. - setState( State.UNCONNECTED ); - - } - - protected void handleSocketCloseException( IOException ioe ) - { - log.log(Level.WARNING, "Error closing socket.", ioe ); - } - - /** - * Signals to trigger a state change. Won't actually send a state change - * until a previous attempt at changing the state finishes. This is - * important if one of the state listeners affects the state (ie tries to - * reconnect if we disconnect, etc). - * - * @param newState New state to set connection to. - */ - private void setState( State newState ) - { - if( settingState ) - { - // We are already setting the state. We want to complete changing - // to one state before changing to another, so that we don't have - // out-of-order state change signals. - stateQueue.addLast( newState ); - return; - } - - settingState = true; - - if( state == newState ) - return; - - while( true ) - { - state = newState; - - //log.debug("IRCConnection: State switch: " + state); - - try - { - stateObservers.setChanged(); - stateObservers.notifyObservers( newState ); - } - catch( Throwable e ) - { - log.log(Level.SEVERE, "IRCConnection: State update failed.", e); - } - - if( stateQueue.isEmpty() ) - break; - newState = stateQueue.removeFirst(); - } - - settingState = false; - } - - private class DefaultCommandSender implements CommandSender - { - public CommandSender getNextCommandSender() - { - return null; - } - - public void sendCommand( OutCommand oc ) - { - finalSendCommand( oc.render() ); - } - } - - /** - * Sends the command down the socket, with the required 'CRLF' on the - * end. Waits for a little bit after sending the command so that we don't - * accidentally flood the server. - * - * @param str String to send - */ - private void finalSendCommand( String str ) - { - try - { - synchronized( eventMonitor ) - { - //log.info("IRCConnection: SEND= " + str); - - if( disconnectPending ) - { - //log.debug("IRCConnection: Send cancelled, disconnect pending."); - return; - } - - socketWriter.write( str + "\r\n" ); - socketWriter.flush(); - - try - { - // Slow things down a bit so the server doesn't kill us - // We do this after the send so that if the send fails the - // exception is handled right away. - Thread.sleep( sendDelay ); - } - catch( InterruptedException ie ) - { - // Ignore - } - } - } - catch( IOException ioe ) - { - socketError( ioe ); - } - } - // ----- END IRCConnection ------------------------------------------- -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/InCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/InCommand.java deleted file mode 100644 index a1564d9ec..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/InCommand.java +++ /dev/null @@ -1,99 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.Iterator; - -import f00f.net.irc.martyr.clientstate.ClientState; - -/** - * Defines commands that come from the server. Errors and replies are - * incoming commands. - * - * @see f00f.net.irc.martyr.errors.GenericError - * @see f00f.net.irc.martyr.replies.GenericReply - */ -public interface InCommand extends Command -{ - - /** - * Some commands, when received by the server, can only occur in one - * state. Thus, when this command is received, the protocol should - * assume that it is in that state, and a state change may be - * triggered. A command can use the 'unknown' state to indicate it - * can be received in any state (for example, ping). - * - * @return State associated with command - */ - State getState(); - - /** - * Every incoming command should know how to register itself with the - * command register. - * - * @param commandRegister Command register we want to register with - */ - void selfRegister( CommandRegister commandRegister ); - - /** - * Parses a string and produces a formed command object, if it can. - * Should return null if it cannot form the command object. The - * identifier is usually ignored, except in the special case where - * commands can be identified by multiple identifiers. In that case, - * the behaviour of the command may change in sublte ways. - * - * @param prefix Prefix of the command - * @param identifier ID of the command - * @param params Parameters of the command - * @return InCommand instance for parsed command - */ - InCommand parse( String prefix, String identifier, String params ); - - /** - * Gives the command a copy of the raw string from the server. Called - * by IRCConnection after the command is parsed. - * - * @param str Sets the source string to be parsed - */ - void setSourceString( String str ); - - /** - * Allows a third party to receive a copy of the raw string. - * - * @return The original source string from the server - */ - String getSourceString(); - - /** - * Asks the command to ensure that information it knows about the - * state the server thinks the client is in matches what we have. - * Returns true if state changes were made. - * - * @param state Client state to be updated - * @return True or false if changes were made - */ - boolean updateClientState( ClientState state ); - - - /** - * Returns an iterator of String objects over the attribute names - * for this command. Warning: Still new, support for this is not - * yet widespread. Should return all possible attribute keys, not just - * those that have a value in the current context. - * - * @return Iterator of attribute keys - */ - Iterator getAttributeKeys(); - - /** - * Returns the attribute, or null if the attribute does not exist, - * or is not defined. - * - * @param key Attribute to get value of - * @return Attribute value or null if attribute doesn't exist - */ - String getAttribute( String key ); - -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/InputHandler.java b/EssentialsUpdate/src/f00f/net/irc/martyr/InputHandler.java deleted file mode 100644 index a3830afa9..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/InputHandler.java +++ /dev/null @@ -1,130 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.LinkedList; -import java.io.BufferedReader; -import java.io.IOException; - -/** - * A simple class to help manage input from the stream. - */ -public class InputHandler extends Thread -{ - //static Logger log = Logger.getLogger(InputHandler.class); - - private BufferedReader reader; - private IRCConnection connection; - private final LinkedList messages; - - private final Object eventMonitor; - - private static int serialGen = 0; - private int serialNumber = serialGen++; - private boolean doShutdown = false; - - public InputHandler( BufferedReader reader, - IRCConnection connection, - Object eventMonitor ) - { - - super("InputHandler"); - this.reader = reader; - this.connection = connection; - messages = new LinkedList(); - this.eventMonitor = eventMonitor; - - //log.debug("IRCConnection: New"); - } - - /** - * Set the shutdown flag, so that after next read, or on any error, the thread will just exit. - */ - public void signalShutdown() - { - synchronized(this) - { - doShutdown = true; - } - } - - /** - * @return true if there are messages waiting to be processed. - */ - public boolean pendingMessages() - { - synchronized( messages ) - { - return ! messages.isEmpty(); - } - } - - /** - * Gets the message at the top of the message queue and removes it from the - * message queue. - * - * @return Message from top of list. - */ - public String getMessage() - { - synchronized( messages ) - { - return messages.removeFirst(); - } - } - - /** - * Waits for input from the server. When input arrives, it is added to a - * queue and eventMonitor.notifyAll() is called. - */ - public void run() - { - //log.debug("IRCConnection: Running"); - try{ - - String str; - while( true ) - { - synchronized(this) - { - if( doShutdown ) - { - return; - } - } - str = reader.readLine(); - if( str == null ) - { - connection.socketError( new IOException( "Socket disconnected" ) ); - return; - } - synchronized( messages ) - { - messages.addLast( str ); - } - synchronized( eventMonitor ) - { - eventMonitor.notifyAll(); - } - } - } - catch( IOException ioe ) - { - if( doShutdown ) - { - return; - } - connection.socketError( ioe ); - } - finally - { - //log.debug("IRCConnection: Input handler has DIED!"); - } - } - - public String toString() - { - return "InputHandler[" + serialNumber + "]"; - } - - // ----- END InputHandler -------------------------------------------- -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java deleted file mode 100644 index 5cc39e1a9..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/Mode.java +++ /dev/null @@ -1,103 +0,0 @@ -package f00f.net.irc.martyr; - -/** - * Any class which is to represent a mode must implement this - * interface. They must also implement equals(...) so that if the - * parameter for either mode is null they are equal based on the - * character, and if both parameters are not null, base the equal - * on the character and the parameters being equal. - */ -public interface Mode -{ - /** - * A Mode can be constructed and asked to make copies of itself. - * - * @return New Mode instance - */ - Mode newInstance(); - - /** - * The character that represents this mode (ie o for operator) - * - * @return Character representation of mode - */ - char getChar(); - - /** - * Should return true if this mode requires a parameter. - * - * @return True or false if a param is required for mode - */ - boolean requiresParam(); - - /** - * This mode should be recorded in the list of channel modes. This - * would NOT include such things as operator status, as it is recored - * with the Member object. - * - * @return True or false of the mode should be recorded in the list of channels - */ - boolean recordInChannel(); - - /** - * Determines if there can be multiple versions of this mode in - * the channel. - * - * @return True or false if only one instance of mode can exist per channel - */ - boolean onePerChannel(); - - /** - * Returns the parameter that was set with setParam(...) - * - * @return Parameter that was set previously - */ - String getParam(); - - /** - * Sets the parameter that can be retrieved with getParam() - * - * @param str Parameter to set on mode - */ - void setParam( String str ); - - /** - * Sets the sign of the operation. Must be positive (granting), - * negative (revoking) or nosign (neutral operation). - * - * @param sign Sign (+/-) of the mode - */ - void setSign( Sign sign ); - - /** - * @return the sign of this mode. - */ - Sign getSign(); - - /** - * Finally, the Sign enumeration. - */ - public class Sign - { - public static final Sign POSITIVE = new Sign( "positive" ); - public static final Sign NEGATIVE = new Sign( "negative" ); - public static final Sign NOSIGN = new Sign( "nosign" ); - - private String name; - private Sign( String name ) - { - this.name = name; - } - - public String toString() - { - return name; - } - } - -} - - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/OutCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/OutCommand.java deleted file mode 100644 index 9e25c9ce9..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/OutCommand.java +++ /dev/null @@ -1,24 +0,0 @@ -package f00f.net.irc.martyr; - -/** - * Defines an outgoing command. Outgoing commands are very simple - * because all they need to do is be rendered. Outgoing commands do - * not change our state. - */ -public interface OutCommand extends Command -{ - - /** - * Forms a string appropriate to send to the server, if required. - * Some commands will have no such string, as they are received and not - * sent. The string returned is sent to the server verbatim. - * - * @return Rendered string - */ - String render(); - -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/State.java b/EssentialsUpdate/src/f00f/net/irc/martyr/State.java deleted file mode 100644 index e1e60ce9d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/State.java +++ /dev/null @@ -1,31 +0,0 @@ -package f00f.net.irc.martyr; - -/** - * A simple container for state constants. The state constants here - * are used to specify what state the protocol is in. The State - * object is both the state representitive and the state container. - * This was done so that state could be typesafe and valuesafe. - * - */ -public class State -{ - - public static final State UNCONNECTED = new State("unconnected"); - public static final State UNREGISTERED = new State("unregistered"); - public static final State REGISTERED = new State("registered"); - public static final State UNKNOWN = new State("unknown/any"); - - private String stateName; - - private State( String str ) - { - stateName = str; - } - - public String toString() - { - return stateName; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/StateObserver.java b/EssentialsUpdate/src/f00f/net/irc/martyr/StateObserver.java deleted file mode 100644 index 4b7a6693c..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/StateObserver.java +++ /dev/null @@ -1,8 +0,0 @@ -package f00f.net.irc.martyr; - -/** - * Should the state and state observer be one? - */ -public class StateObserver extends ForwardObservable -{ -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/TimerTaskCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/TimerTaskCommand.java deleted file mode 100644 index 00ab56f56..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/TimerTaskCommand.java +++ /dev/null @@ -1,57 +0,0 @@ -package f00f.net.irc.martyr; - -import java.util.TimerTask; - -// TODO: BD: Unit test -// TODO: BD: synchronization semantics? - -/** - * This class delays sending a command to the IRC connection. - * - * @author Morgan Christiansson - */ -public class TimerTaskCommand extends TimerTask -{ - - private IRCConnection _conn; - private OutCommand _cmd; - public TimerTaskCommand(IRCConnection conn, OutCommand cmd) - { - _conn = conn; - _cmd = cmd; - } - /* (non-Javadoc) - * @see java.util.TimerTask#run() - */ - public synchronized void run() - { - if( !isScheduled ) - return; - - _conn.sendCommand(_cmd); - isScheduled = false; - } - - private boolean isScheduled = true; - - /* (non-Javadoc) - * @see java.util.TimerTask#cancel() - */ - public synchronized boolean cancel() - { - boolean ret = super.cancel(); - isScheduled = false; - return ret; - } - - /** - * @return true if the command has yet to run or is running, false - * otherwise. - */ - public synchronized boolean isScheduled() - { - return isScheduled; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java deleted file mode 100644 index d1d39c31d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java +++ /dev/null @@ -1,373 +0,0 @@ -package f00f.net.irc.martyr.clientstate; - -import java.util.Date; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Vector; - -import f00f.net.irc.martyr.Command; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.Mode; -import f00f.net.irc.martyr.modes.channel.OperMode; -import f00f.net.irc.martyr.modes.channel.VoiceMode; -import f00f.net.irc.martyr.util.FullNick; -//import org.apache.log4j.Logger; - -/** - * Channel is simply a repository for information about a channel. - * Contains channel name, topic, who created the topic, when the topic - * was created, who is in the channel, mode, etc. - * - *

If a user of the framework wishes to use their own Member object - * (to trap events like setting/removing ops), then subclass - * Channel and add a method as follows.

- * - *
- * public Member makeMember( String member )
- * {
- *     return MyMemberSubClass( member ) );
- * }
- * 
- * - *

Each of the methods in Channel that need to create a Member - * object (many are just temporary members, for the enhanced 'equals') - * calls makeMember instead of new Member(...). That is why this - * version of addMember is protected, so that a part of the framework - * won't do something silly like:

- * - *
- *      ...
- *      channel.addMember( new Member( member ) );
- *      ...
- * 
- */ -public class Channel -{ - - //static Logger log = Logger.getLogger(Channel.class); - - private String name = null; - private String topic = null; - private String topicAuthor = null; - private Date topicDate = null; - private Date creationDate = null; - - private List modes = null; - - /** - * Hopefully we can replace this with a more useful data structure. - * This is a vector of Member objects. - */ - private Vector members; - - public Channel( String chanName ) - { - this.name = chanName; - members = new Vector(); - modes = new LinkedList(); - } - - public String getName() - { - return name; - } - - protected void addMember( Member member ) - { - members.addElement( member ); - } - - /** - * Adds the member to the channel. - * - * @param member Member to add to the channel - * @param why Command that caused the member to be added - * @deprecated Use addMember( String, InCommand ) - * instead. - */ - public void addMember( String member, Command why ) - { - addMember( makeMember( member ) ); - } - - /** - * Adds the member to the channel. - * - * @param member Nick to add to the channel - * @param why Command that caused the member to be added - */ - public void addMember( String member, InCommand why ) - { - addMember( makeMember( member ) ); - } - - - /** - * @param nick Nick to add to the channel - * @param why Command that caused the member to be added - * @deprecated Use addMember( FullNick, InCommand ) intead. - */ - public void addMember( FullNick nick, Command why ) - { - addMember( makeMember( nick.getNick() )); - } - - /** - * @param nick Nick to add to the channel - * @param why Command that caused the member to be added - * Adds the member to the channel. Just calls nick.getNick(). - */ - public void addMember( FullNick nick, InCommand why ) - { - addMember( nick.getNick(), why ); - } - - /** - * Removes the user from the channel. Ignores leading @ or + symbols. - * This is the cononical version of removeMember. - * @param member Nick of the person leaving. - * @param why Command issed that caused this action. - */ - public void removeMember( String member, InCommand why ) - { - removeMember( makeMember( member ) ); - } - - /** - * @param member Nick to remove from channel - * @param why Command that caused removal - * @deprecated Use removeMember( String, InCommand ) instead. - * */ - public void removeMember( String member, Command why ) - { - removeMember( makeMember( member ) ); - } - - /** - * @param member Member to remove from channel - * @param why Command that caused removal - * @deprecated Use removeMember( FullNick, InCommand ) instead. - * */ - public void removeMember( FullNick member, Command why ) - { - removeMember( member, (InCommand)why ); - } - - /** - * Simply a wrapper to allow FullNicks to be used. Calls the string - * version of removeMember with nick.getNick(). - * - * @param nick Nick to remove from channel - * @param why Command that caused removal - */ - public void removeMember( FullNick nick, InCommand why ) - { - removeMember( nick.getNick(), why ); - } - - protected void removeMember( Member compareTo ) - { - for( int i = 0; i < members.size(); ++i ) - { - if( (members.elementAt( i )).equals( compareTo ) ) - { - members.removeElementAt( i ); - return; - } - } - } - - /** - * Informs the channel of a mode change. A mode change might be for the - * channel (such as l, n, or t) or for a user on this channel (such as - * o). - * - * @param mode Mode to set on the channel - */ - public void setMode( Mode mode ) - { - // Note that Modes are supposed to be equal if the character is - // equal. Thus, we can remove a mode from the set, even though it - // is different because its sign or parameters may be different. - if( mode.onePerChannel() && modes.contains( mode ) ) - { - modes.remove( mode ); - } - - if( (mode.getSign() != Mode.Sign.NEGATIVE) && mode.recordInChannel() ) - { - modes.add( mode ); - } - - if( mode instanceof OperMode ) - { - OperMode oMode = (OperMode)mode; - Member member = findMember( oMode.getParam() ); - - member.setOps( oMode.getSign() == Mode.Sign.POSITIVE ); - } - else if( mode instanceof VoiceMode ) - { - VoiceMode vMode = (VoiceMode)mode; - Member member = findMember( vMode.getParam() ); - - member.setVoice( vMode.getSign() == Mode.Sign.POSITIVE ); - } - } - - public Iterator getModes() - { - return modes.iterator(); - } - - /** - * Returns an enumeration of Member objects, in no particular order. - * - * @return List of members in the channel - */ - public Enumeration getMembers() - { - return members.elements(); - } - - /** - * Determines if the nick is in the channel. Nick can be in the form - * "@sork" or "+sork" or just "sork", for example. - * - * @param nick Nick of member to check - * @return True or false if the member is in this channel. - */ - public boolean isMemberInChannel( String nick ) - { - return isMemberInChannel( makeMember( nick ) ); - } - - /** - * Determines if the member is in this channel. - * - * @param member Member to check - * @return True or false if the member is in this channel. - */ - protected boolean isMemberInChannel( Member member ) - { - return findMember( member ) != null; - } - - /** - * Finds the Member object associated with a specific nick. Ignores - * prefixed + or @. - * - * @param nick Nick to check whether it's a member of the channel or not - * @return Member object for specified nick, if it exists (null if not) - */ - public Member findMember( String nick ) - { - return findMember( makeMember( nick ) ); - } - - protected Member findMember( Member member ) - { - Enumeration membersE = getMembers(); - while( membersE.hasMoreElements() ) - { - Member memberCompare = (Member)membersE.nextElement(); - - if( memberCompare.equals( member ) ) - { - return memberCompare; - } - } - - return null; - } - - public void setTopic( String topic ) - { - //log.debug(getName()+": Topic: " + topic); - this.topic = topic; - } - - public String getTopic() - { - return topic; - } - - public Date getTopicDate() - { - return topicDate; - } - - public void setTopicDate( Date date ) - { - //log.debug(getName()+": Topic date: " + date); - this.topicDate = date; - } - - public Date getCreationDate() - { - return creationDate; - } - - public void setCreationDate( Date date ) - { - //log.debug(getName()+": Creation date: " + date); - this.creationDate = date; - } - - public String getTopicAuthor() - { - return topicAuthor; - } - - public void setTopicAuthor( String author ) - { - //log.debug(getName()+": Topic by: " + author); - this.topicAuthor = author; - } - - /** - * To use a customized Member class, override this. - * - * @param nick Nickname to create a member object for - * @return Member object for nick - */ - protected Member makeMember( String nick ) - { - return new Member( nick ); - } - - - /** - * Determines if the string represents a channel name or not. - * - * @param str String to test if it's a channel or not - * @return True or false if a string looks like a channel - */ - public static boolean isChannel( String str ) - { - return str.charAt(0) == '#' || str.charAt(0) == '!' || str.charAt(0) == '&'; - } - - /** - * Compares the two channel names for equality. Returns false if - * either are null. - * - * @param one Left side of comparison - * @param two Right side of comparison - * @return True or false whether two channels are equal, false of either are null/ - */ - public static boolean areEqual( String one, String two ) - { - if( one == null || two == null ) - { - return false; - } - - return one.equalsIgnoreCase( two ); - } -} - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java deleted file mode 100644 index c508463d9..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Original version: Ben Damm - * Changes by: mog - * - Added isOnChannel - * - */ -package f00f.net.irc.martyr.clientstate; - -import java.util.Enumeration; -import java.util.Hashtable; - -import f00f.net.irc.martyr.util.FullNick; -//import org.apache.log4j.Logger; - -/** - *

Maintains a list of client-related facts such as what channels we - * are in, who else is in the channels, what our nick is, etc.

- * - *

ClientState is a critical part of martyr. To get access to events - * that change the client state, the framework user can subclass - * ClientState and then pass the subclass to the IRCConnection's - * constructor. Then, when a command detects a change in client - * state, it will call the corresponding method in the custom - * ClientState.

- * - *

If a user of the framework wishes to grab client state information - * about a channel (when a user joins, when a user leaves, topic - * change, etc), the user can do so in a similar manner. Simply - * override the 'addChannel(String)' method to instantiate their own - * Channel subclass, and call the protected 'addChannel' method. See - * the addChannel method for an example. - *

- * - */ -public class ClientState -{ - - //static Logger log = Logger.getLogger(ClientState.class); - - private FullNick nick = null; - private String user = ""; - private String name = ""; - private String pass = null; - private String server = ""; - private int port = -1; - - // Hashtable is threadsafe so we don't have to be. - protected Hashtable channels = new Hashtable(); - - public void setNick( FullNick nick ) - { - if( nick == null ) - { - //log.debug("ClientState: Set nick to null"); - } - else - { - //log.debug("ClientState: Set nick to \"" + nick + "\""); - } - this.nick = nick; - } - - public FullNick getNick() - { - return nick; - } - - public void setUser( String user ) - { - this.user = user; - } - - /** - * @return the username that was used to register. - * */ - public String getUser() - { - return user; - } - - public void setName( String name ) - { - this.name = name; - } - - /** - * @return the name (any arbitrary string) that was used to register. - * */ - public String getName() - { - return name; - } - - /** - * @return the password that was used to register. - */ - public String getPass() - { - return pass; - } - - public void setPass(String pass) - { - this.pass = pass; - } - - public void setServer( String server ) - { - this.server = server; - } - - public String getServer() - { - return server; - } - - public void setPort( int port ) - { - this.port = port; - } - - public int getPort() - { - return port; - } - - /** - *

Adds a channel to the list of channels we know about. If you - * want to supply your own Channel object, override this method - * with:

- *
-     * public void addChannel( String channame )
-     * {
-     *     addChannel( new MyChannel( channame ) );
-     * }
-     * 
- * - * @param channame Channel to add to list of channels - */ - public void addChannel( String channame ) - { - addChannel( new Channel( channame ) ); - } - - protected void addChannel( Channel channel ) - { - //log.debug("ClientState: Channel added: " + channel.getName()); - channels.put( channel.getName().toLowerCase(), channel ); - } - - public Channel getChannel( String chanName ) - { - return channels.get( chanName.toLowerCase() ); - } - - /** - * Removes a channel from the state, does nothing if the channel name - * is invalid. - * Should we throw an exception here? - * - * @param channel Channel to remove from list - */ - public void removeChannel( String channel ) - { - //log.debug("ClientState: Channel removed: " + channel); - channels.remove( channel.toLowerCase() ); - } - - public boolean isOnChannel( String channel ) - { - for (Enumeration iter = getChannelNames(); iter.hasMoreElements();) - { - if(channel.equalsIgnoreCase((String) iter.nextElement())) - { - return true; - } - } - return false; - } - - public Enumeration getChannelNames() - { - return channels.keys(); - } - - public Enumeration getChannels() - { - return channels.elements(); - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java deleted file mode 100644 index 489f21961..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java +++ /dev/null @@ -1,114 +0,0 @@ -package f00f.net.irc.martyr.clientstate; - -import f00f.net.irc.martyr.util.FullNick; - -/** - *

This class allows channels to keep track of individual users. Each - * user in the channel has a nick and has voice, ops, both, or none. - * Note that nicks can change, but the information we have about that - * person does not.

- * - *

Control over events that happen to this class can be obtained in - * a similar fashion to how control for the Channel is taken from - * ClientState.

- */ -public class Member -{ - - private FullNick nick; - private boolean hasOpsV = false; - private boolean hasVoiceV = false; - - /** - *

Strips off the leading 'at' or 'plus', sets ops or voice, and - * keeps the nick. Calls the methods setVoice(...) and - * setOps(...) from the constructor, if those conditions - * are true. The nick is set before setVoice or setOps are - * called.

- * - * @param nickStr Nick of member - */ - public Member( String nickStr ) - { - char first = nickStr.charAt(0); - String shortNick = nickStr.substring(1, nickStr.length() ); - if( first == '@' ) - { - nick = new FullNick( shortNick ); - setOps( true ); - } - else if( first == '+' ) - { - nick = new FullNick( shortNick ); - setVoice( true ); - } - else - { - nick = new FullNick( nickStr ); - } - } - - /** - * Does a nick-wise compare. - * - * @param member Member to compare against - * @return True or false of this member equals the other one - */ - public boolean equals( Member member ) - { - return equals( member.nick ); - } - - public boolean equals( FullNick fullNick ) - { - return nick.equals( fullNick ); - } - - public boolean equals( Object o ) - { - if( o instanceof Member ) - return equals( (Member)o ); - else if( o instanceof FullNick ) - return equals( (FullNick)o ); - else return false; - } - - public int hashCode() - { - return nick.hashCode(); - } - - public void setOps( boolean ops ) - { - hasOpsV = ops; - } - - public void setVoice( boolean voice ) - { - hasVoiceV = voice; - } - - public boolean hasOps() - { - return hasOpsV; - } - - public boolean hasVoice() - { - return hasVoiceV; - } - - public void setNick( FullNick nick ) - { - this.nick = nick; - } - - public FullNick getNick() - { - return nick; - } - -} - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractCommand.java deleted file mode 100644 index a3e3ef2c2..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractCommand.java +++ /dev/null @@ -1,32 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.OutCommand; - -/** - * Defines a generic command. Most commands will simply have to - * override the getIrcIdentifier method and implement the parse and - * render methods using convenience methods. - */ -public abstract class AbstractCommand extends AbstractInCommand implements OutCommand -{ - - /** - * Forms a string appropriate to send to the server. All commands can - * be sent by the client. - */ - public String render() - { - // no prefix, since we are sending as a client. - return getIrcIdentifier() + " " + renderParams(); - } - - /** - * Renders the parameters of this command. - * - * @return String of rendered parameters - */ - public abstract String renderParams(); - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java deleted file mode 100644 index 97f305241..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java +++ /dev/null @@ -1,174 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.CommandRegister; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.clientstate.ClientState; - -/** - * Defines a generic command. Most commands will simply have to - * override the getIrcIdentifier method and implement the parse and - * render methods using convenience methods. - */ -public abstract class AbstractInCommand implements InCommand -{ - - protected Map attributes = new HashMap(); - - protected AbstractInCommand() - { - } - - protected AbstractInCommand( String[] attributeNames ) - { - for (String attributeName : attributeNames) { - attributes.put(attributeName, null); - } - } - - public String getAttribute( String key ) - { - return attributes.get( key ); - } - - public Iterator getAttributeKeys() - { - return Collections.unmodifiableSet( attributes.keySet() ).iterator(); - } - - protected void setAttribute( String key, String value ) - { - attributes.put( key, value ); - } - - private String sourceString; - - /** - * Some commands, when received by the server, can only occur in one - * state. Thus, when this command is received, the protocol should - * assume that it is that state. A command can use the 'unknown' - * state to indicate it can be received in any state (for example, - * ping). Most commands will occur in the REGISTERED state, so for a - * few exeptions, commands can leave this alone. - */ - public State getState() - { - return State.REGISTERED; - } - - /** - * Every command should know how to register itself (or not) with the - * command parsing engine. If a command is available under mutiple - * identifiers, then this method can be overridden and the addCommand - * method can be called multiple times. - */ - public void selfRegister( CommandRegister commandRegister ) - { - commandRegister.addCommand( getIrcIdentifier(), this ); - } - - /** - * Parses a string and produces a formed command object, if it can. - * Should return null if it cannot form the command object. - */ - public abstract InCommand parse( String prefix, String identifier, String params ); - - /** - * By default, commands do not update the client state. - */ - public boolean updateClientState( ClientState state ) - { - return false; - } - - /** - * Utility method to make parsing easy. Provides parameter n, where - * n=0 is the first parameter. Parses out the : and considers - * anything after a : to be one string, the final parameter. - * - * If the index doesn't exist, returns null. Should it throw - * IndexOutOfBoundsException? No, some commands may have optional - * fields. - * - * @param params String with parameters in it - * @param num Position number of parameter to be requested - * @return Parameter specified by id in params string - */ - public String getParameter( String params, int num ) - { - int colonIndex = params.indexOf( " :" ); - colonIndex++; // Skip the space, we just needed it to be sure it's really a "rest of line" colon - String textParam = null; - String spaceParams; - - if( colonIndex < 0 ) - { - spaceParams = params; - } - else if( colonIndex == 0 ) - { - if( num == 0 ) - return params.substring( 1, params.length() ); - else - return null; - // throw exception? - } - else - { - // colon index > 0, so we have at least one parameter before - // the final parameter. - spaceParams = params.substring( 0, colonIndex ).trim(); - textParam = params.substring( colonIndex + 1, params.length() ); - } - - StringTokenizer tokens = new StringTokenizer( spaceParams, " " ); - - while( tokens.hasMoreTokens() && num > 0 ) - { - // strip off tokensi - --num; - tokens.nextToken(); - } - - if( num == 0 && tokens.hasMoreTokens() ) - return tokens.nextToken(); - if( num == 0 && !tokens.hasMoreTokens() ) - return textParam; - - - return null; - // throw exception? - } - - public int getIntParameter( String params, int paramnum, int defaultNum ) - { - try - { - return Integer.parseInt( getParameter( params, paramnum ) ); - } - catch( NumberFormatException nfe ) - { - return defaultNum; - } - - } - - public void setSourceString( String source ) - { - this.sourceString = source; - } - - public String getSourceString() - { - return sourceString; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ActionCtcp.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ActionCtcp.java deleted file mode 100644 index f599f16b7..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ActionCtcp.java +++ /dev/null @@ -1,12 +0,0 @@ -package f00f.net.irc.martyr.commands; - -/** - * ActionCtcp allows the application to do a '/me'. - */ -public class ActionCtcp extends CtcpMessage -{ - public ActionCtcp( String dest, String message ) - { - super( dest, "ACTION " + message ); - } -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ChannelModeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ChannelModeCommand.java deleted file mode 100644 index f8305852b..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ChannelModeCommand.java +++ /dev/null @@ -1,189 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.Mode; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.modes.channel.AnonChannelMode; -import f00f.net.irc.martyr.modes.channel.BanMode; -import f00f.net.irc.martyr.modes.channel.ExceptionMode; -import f00f.net.irc.martyr.modes.channel.InviteMaskMode; -import f00f.net.irc.martyr.modes.channel.InviteOnlyMode; -import f00f.net.irc.martyr.modes.channel.KeyMode; -import f00f.net.irc.martyr.modes.channel.LimitMode; -import f00f.net.irc.martyr.modes.channel.ModeratedMode; -import f00f.net.irc.martyr.modes.channel.NoExtMsgMode; -import f00f.net.irc.martyr.modes.channel.OperMode; -import f00f.net.irc.martyr.modes.channel.PrivateMode; -import f00f.net.irc.martyr.modes.channel.SecretMode; -import f00f.net.irc.martyr.modes.channel.TopicLockMode; -import f00f.net.irc.martyr.modes.channel.VoiceMode; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Defines the ChannelMode command. Can be used to send a Channel - * mode. For receiving, this defines which channel modes Martyr knows - * about and passes them on to the Channel object. Note that the - * actual logic of what happens when a mode arrives lies in the - * clientstate.Channel object. - */ -public class ChannelModeCommand extends ModeCommand -{ - - private String prefix; - private String channelName; - private FullNick sender; - - private List modes; - - private static HashMap modeTypes; - - /** - * For receiving a mode command. - * @param prefix Currently unused prefix string - * @param channelName Channel that the mode change is in reference to - * @param params List of params to be parsed - */ - public ChannelModeCommand( String prefix, String channelName, - StringTokenizer params ) - { - makeModes(); - - this.prefix = prefix; - this.channelName = channelName; - - modes = parseModes( modeTypes, params ); - - // System.out.println( modes ); - } - - /** - * For sending a mode discovery. - * - * @param channelName Channel that the mode change is in reference to - */ - public ChannelModeCommand( String channelName ) - { - sender = null; - this.channelName = channelName; - - // Empty list, no modes. - modes = new LinkedList(); - } - - public void makeModes() - { - if( modeTypes == null ) - { - modeTypes = new HashMap(); - - registerMode( modeTypes, new BanMode() ); - registerMode( modeTypes, new KeyMode() ); - registerMode( modeTypes, new OperMode() ); - registerMode( modeTypes, new VoiceMode() ); - registerMode( modeTypes, new LimitMode() ); - // registerMode( modeTypes, new QuietMode() ); - registerMode( modeTypes, new SecretMode() ); - registerMode( modeTypes, new PrivateMode() ); - registerMode( modeTypes, new NoExtMsgMode() ); - registerMode( modeTypes, new ExceptionMode() ); - registerMode( modeTypes, new TopicLockMode() ); - registerMode( modeTypes, new ModeratedMode() ); - registerMode( modeTypes, new InviteMaskMode() ); - registerMode( modeTypes, new InviteOnlyMode() ); - registerMode( modeTypes, new AnonChannelMode() ); - } - } - - /** - * Shouldn't be called, as ModeCommand should be responsible for parsing - * and creating this class. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - throw new IllegalStateException( "Don't call this method!" ); - } - - public String render() - { - return "MODE " + channelName + renderParams(); - } - - public String renderParams() - { - Iterator modesI = modes.iterator(); - - String modes = ""; - String params = ""; - - while( modesI.hasNext() ) - { - Mode mode = (Mode)modesI.next(); - - if( mode.getSign() != Mode.Sign.NOSIGN ) - { - modes += (mode.getSign() == Mode.Sign.POSITIVE ? "+" : "-" ); - } - modes += mode.getChar(); - - if( mode.getParam() != null ) - { - // Does the parameter list already have params? - // If so, stick in a space. - if( params.length() > 0 ) - { - params += " "; - } - params += mode.getParam(); - } - } - - return modes + " " + params; - } - - public String getChannel() - { - return channelName; - } - - public FullNick getSender() - { - return sender; - } - - public String getPrefix() { - return prefix; - } - - /** - * Passes the modes on to the clientstate.Channel object. - */ - public boolean updateClientState( ClientState state ) - { - boolean changed = false; - - Iterator modesI = modes.iterator(); - Channel channel = state.getChannel( channelName ); - - while( modesI.hasNext() ) - { - Mode mode = (Mode)modesI.next(); - - channel.setMode( mode ); - - changed = true; - } - - return changed; - } - - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpMessage.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpMessage.java deleted file mode 100644 index 6012aa0ab..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpMessage.java +++ /dev/null @@ -1,129 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.util.FullNick; - -/** - * This facilitates the sending and receiving of CTCP messages. Upon - * receiving a message, MessageCommand checks to see if it is a CTCP, - * and if it is, it instantiates this class instead of a - * MessageCommand. You can then use the getAction() and getMessage() - * methods to retreive the action and payload, respectively. - * - * @see MessageCommand - */ -public class CtcpMessage extends MessageCommand -{ - private String actionStr; - - /** - * Use this to send a CTCP message. This simply wraps the string - * with the CTCP tags, \001. - * - * @param dest Target of CTCP message - * @param message Actual CTCP message - */ - public CtcpMessage( String dest, String message ) - { - super( dest, "\001" + message + "\001" ); - } - - public CtcpMessage( String dest, String action, String message ) - { - this( dest, action + " " + message ); - } - - /** - * This is only to be called by MessageCommand, as a way of - * receiving a Ctcp message. It strips the \001's off and holds - * the message left over. - * - * @param from Nick that sent the message - * @param dest Target of the CTCP message - * @param message Actual CTCP message - */ - protected CtcpMessage( FullNick from, String dest, String message ) - { - super( from, dest, getMessageStr( stripCtcpWrapper( message ) ) ); - - actionStr = getActionStr( stripCtcpWrapper( message ) ); - } - - /** - * Returns the action of this CTCP. Use getMessage() to retreive - * the payload of the action. - * - * @return The action specified by the CTCP message - */ - public String getAction() - { - return actionStr; - } - - /** - * Given a stripped CTCP message, returns the ctcp action string. - * - * @param msg Message to be parsed into an action - * @return Action string from message - */ - public static String getActionStr( String msg ) - { - StringTokenizer tokens = new StringTokenizer( msg ); - return tokens.nextToken(); - } - - public static String getMessageStr( String msg ) - { - String acn = getActionStr( msg ); - return msg.substring( acn.length() ).trim(); - } - - /** - * If the string is wrapped with CTCP signal chars (\001) returns - * true. - * - * @param msg String to check whether it's a CTCP message or not - * @return True or false if it's a CTCP message - */ - public static boolean isCtcpString( String msg ) - { - return msg.charAt(0) == '\001' && msg.charAt(msg.length()-1) == '\001'; - } - - /** - * Strips a CTCP wrapper, if there is one. - * - * @param msg String to be stripped - * @return Stripped string - */ - public static String stripCtcpWrapper( String msg ) - { - if( isCtcpString( msg ) ) - { - return msg.substring( 1, msg.length()-1 ); - } - else - { - return msg; - } - } - - /** - * Dysfunctional. Returns dat immediatly. - */ - /*public static byte[] escapeMsg( byte[] dat ) - { - return dat; - }*/ - - /** - * Dysfunctional. Returns dat immediatly. - */ - /*public static byte[] unEscapeMsg( byte[] dat ) - { - return dat; - }*/ -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpNotice.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpNotice.java deleted file mode 100644 index e40c0a01a..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/CtcpNotice.java +++ /dev/null @@ -1,131 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.util.FullNick; - -/** - * This facilitates the sending and receiving of CTCP messages. Upon - * receiving a message, MessageCommand checks to see if it is a CTCP, - * and if it is, it instantiates this class instead of a - * MessageCommand. You can then use the getAction() and getMessage() - * methods to retreive the action and payload, respectively. - * - * @see NoticeCommand - */ -public class CtcpNotice extends NoticeCommand -{ - private String actionStr; - - /** - * Use this to send a CTCP message. This simply wraps the string - * with the CTCP tags, \001. - * - * @param dest Target of CTCP message - * @param message Actual CTCP message - */ - public CtcpNotice( String dest, String message ) - { - super( dest, "\001" + message + "\001" ); - } - - public CtcpNotice( String dest, String action, String message ) - { - this( dest, action + " " + message ); - - actionStr = action; - } - - /** - * This is only to be called by MessageCommand, as a way of - * receiving a Ctcp message. It strips the \001's off and holds - * the message left over. - * - * @param from Nick that sent the message - * @param dest Target of the CTCP message - * @param message Actual CTCP message - */ - protected CtcpNotice( FullNick from, String dest, String message ) - { - super( from, dest, getMessageStr( stripCtcpWrapper( message ) ) ); - - actionStr = getActionStr( stripCtcpWrapper( message ) ); - } - - /** - * Returns the action of this CTCP. Use getMessage() to retreive - * the payload of the action. - * - * @return The action specified by the CTCP message - */ - public String getAction() - { - return actionStr; - } - - /** - * Given a stripped CTCP message, returns the ctcp action string. - * - * @param msg Message to be parsed into an action - * @return Action string from message - */ - public static String getActionStr( String msg ) - { - StringTokenizer tokens = new StringTokenizer( msg ); - return tokens.nextToken(); - } - - public static String getMessageStr( String msg ) - { - String acn = getActionStr( msg ); - return msg.substring( acn.length() ).trim(); - } - - /** - * If the string is wrapped with CTCP signal chars (\001) returns - * true. - * - * @param msg String to check whether it's a CTCP message or not - * @return True or false if it's a CTCP message - */ - public static boolean isCtcpString( String msg ) - { - return msg.charAt(0) == '\001' && msg.charAt(msg.length()-1) == '\001'; - } - - /** - * Strips a CTCP wrapper, if there is one. - * - * @param msg String to be stripped - * @return Stripped string - */ - public static String stripCtcpWrapper( String msg ) - { - if( isCtcpString( msg ) ) - { - return msg.substring( 1, msg.length()-1 ); - } - else - { - return msg; - } - } - - /** - * Dysfunctional. Returns dat immediatly. - */ - /*public static byte[] escapeMsg( byte[] dat ) - { - return dat; - }*/ - - /** - * Dysfunctional. Returns dat immediatly. - */ - /*public static byte[] unEscapeMsg( byte[] dat ) - { - return dat; - }*/ -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/InviteCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/InviteCommand.java deleted file mode 100644 index 9010a4322..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/InviteCommand.java +++ /dev/null @@ -1,90 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; -import f00f.net.irc.martyr.util.ParameterIterator; - -/** - * @author Morgan Christiansson - */ -public class InviteCommand extends AbstractCommand { - - private String _channel; - private String _nick; - private FullNick _user; - - /** For use as a factory */ - public InviteCommand() - { - _channel = null; - _nick = null; - _user = null; - } - - private InviteCommand(FullNick user, String nick, String channel) - { - _user = user; - _nick = nick; - _channel = channel; - } - - public InviteCommand(String nick, String channel) - { - _nick = nick; - _channel = channel; - } - - public InviteCommand(FullNick nick, String channel) - { - this(nick.getNick(), channel); - } - - /* (non-Javadoc) - * @see f00f.net.irc.martyr.Command#parse(java.lang.String, java.lang.String, java.lang.String) - */ - public InCommand parse(String prefix, String identifier, String params) - { - ParameterIterator iter = new ParameterIterator(params); - return new InviteCommand( new FullNick( prefix ), (String)iter.next(), (String)iter.next() ); - } - - /* (non-Javadoc) - * @see f00f.net.irc.martyr.commands.AbstractCommand#getIrcIdentifier() - */ - public String getIrcIdentifier() - { - return "INVITE"; - } - - /* (non-Javadoc) - * @see f00f.net.irc.martyr.commands.AbstractCommand#renderParams() - */ - public String renderParams() - { - return _nick+" "+_channel; - } - - /** - * @return The channel invited to. */ - public String getChannel() - { - return _channel; - } - - /** - * @return The nick sending the invite. - */ - public String getNick() - { - return _nick; - } - - /** - * @return The user the invite is sent to. - */ - public FullNick getUser() - { - return _user; - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/IsonCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/IsonCommand.java deleted file mode 100644 index 8df571a8e..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/IsonCommand.java +++ /dev/null @@ -1,144 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.CommandRegister; - -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; - -/** - * Defines the ISON command, which is used to determine if a user or a list of users is online. - * - * @author Daniel Henninger - */ -public class IsonCommand extends AbstractCommand -{ - - public static final String IDENTIFIER_PRIMARY = "ISON"; - public static final String IDENTIFIER_SECONDARY = "303"; - - /* List of nicks that we will check for online status */ - List nicks = new ArrayList(); - - /* Destination nick */ - String dest = null; - - /** - * No parameter passed to the ISON is not valid. This is used for factories. - */ - public IsonCommand() - { - // Nothing to do - } - - /** - * Check online status of a single nickname. - * - * @param nick Nick you want to check the online status of. - */ - public IsonCommand(String nick) - { - this.nicks.add(nick); - } - - public IsonCommand(String dest, String nick) { - this.dest = dest; - this.nicks.add(nick); - } - - /** - * Check online status of a number of nicknames. - * - * @param nicks List of nicks you want to check the online status of. - */ - public IsonCommand(List nicks) - { - this.nicks.addAll(nicks); - } - - public IsonCommand(String dest, List nicks) { - this.dest = dest; - this.nicks.addAll(nicks); - } - - /** - * @see AbstractCommand#parse(String, String, String) - */ - public InCommand parse(String prefix, String identifier, String params) - { - // when the command is used as a reply, the nick is parameter 0 and the rest are parameter 1. - if ( identifier.equals( IDENTIFIER_SECONDARY ) ) { - String nickParam = getParameter(params, 1); - List nicks = Arrays.asList(nickParam.split(" ")); - return new IsonCommand(getParameter(params, 0), nicks); - } - else { - String nickParam = getParameter(params, 0); - List nicks = Arrays.asList(nickParam.split(" ")); - return new IsonCommand(nicks); - } - } - - /** - * @see f00f.net.irc.martyr.commands.AbstractCommand#renderParams() - */ - public String renderParams() - { - String ret = ""; - if (nicks.size() > 0) { - Boolean isFirst = true; - for (String nick : nicks) { - if (isFirst) { - ret = ret + nick; - isFirst = false; - } - else { - ret = ret + " " + nick; - } - } - } - return ret; - } - - /** - * @see f00f.net.irc.martyr.Command#getIrcIdentifier() - */ - public String getIrcIdentifier() - { - // - // This command uses "ISON" on outgoing, so that is why we use - // "ISON" here instead of "303". - // - return IDENTIFIER_PRIMARY; - } - - /** - * @see AbstractCommand#selfRegister(f00f.net.irc.martyr.CommandRegister) - */ - public void selfRegister(CommandRegister commandRegister) - { - commandRegister.addCommand( IDENTIFIER_PRIMARY, this ); - commandRegister.addCommand( IDENTIFIER_SECONDARY, this ); - } - - /** - * Retrieves the target of the ISON command - * - * @return Target of command - */ - public String getDest() { - return dest; - } - - /** - * Retrieves the list of nicks that are online after an ISON command - * - * @return List of online nicks - */ - public List getNicks() - { - return nicks; - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/JoinCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/JoinCommand.java deleted file mode 100644 index 32f2d1e75..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/JoinCommand.java +++ /dev/null @@ -1,131 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.util.FullNick; -import java.util.logging.Logger; - - -/** - * Defines JOIN command. - */ -public class JoinCommand extends AbstractCommand -{ - - static Logger log = Logger.getLogger(JoinCommand.class.getName()); - - private String channel; - private String secret; - private FullNick user; - - /** For use as a factory */ - public JoinCommand() - { - this.user = null; - this.channel = null; - this.secret = null; - } - - /** - * This constructor is used with an incoming JOIN command from the server. - * - * @param user User that joined the channel - * @param channel Channel that was joined - */ - private JoinCommand( FullNick user, String channel ) - { - this.user = user; - this.channel = channel; - this.secret = null; - } - - /** - * This constructor is used to make a request to join a channel that - * requires a secret key to join. - * - * @param channel The channel - * @param secret The secret key required to enter the channel, or null of - * none. - */ - public JoinCommand( String channel, String secret ) - { - this.secret = secret; - this.user = null; - this.channel = channel; - } - - /** - * This constructor is used to make a request to join a channel. - * - * @param channel Channel that will be joined - */ - public JoinCommand( String channel ) - { - this.secret = null; - this.user = null; - this.channel = channel; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new JoinCommand( new FullNick( prefix ), getParameter( params, 0 ) ); - } - - public String getIrcIdentifier() - { - return "JOIN"; - } - - public String renderParams() - { - if( secret == null ) - return channel; - else - return channel + " " + secret; - } - - public String getChannel() - { - return channel; - } - - public String getSecret() - { - return secret; - } - - public FullNick getUser() - { - return user; - } - - public boolean weJoined( ClientState state ) - { - return user.equals( state.getNick() ); - } - - public boolean updateClientState( ClientState state ) - { - if( weJoined( state ) ) - { - // We've joined a group. - //log.debug("JOIN: We've joined " + channel); - state.addChannel( channel ); - return true; - } - else - { - // Someone else joined the group. - //log.debug("JOIN: " + user + " joined " + channel); - // 1) Grab group - Channel channelObj = state.getChannel( channel ); - // 2) Add user - channelObj.addMember( user, this ); - return true; - } - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/KickCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/KickCommand.java deleted file mode 100644 index 96b2731e1..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/KickCommand.java +++ /dev/null @@ -1,110 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.util.FullNick; -import java.util.logging.Logger; - - -/** - * Defines KICK command. - */ -public class KickCommand extends AbstractCommand -{ - - static Logger log = Logger.getLogger(KickCommand.class.getName()); - - private String channel; - private FullNick userKicker; - private FullNick userKicked; - private String comment; - - /** For use as a factory */ - public KickCommand() - { - this( null, null, null, null ); - } - - public KickCommand( FullNick userKicker, String channel, - String userKicked, String comment ) - { - this.userKicker = userKicker; - this.channel = channel; - this.userKicked = new FullNick( userKicked ); - this.comment = comment; - } - - public KickCommand( String channel, String userToKick, String comment ) - { - this( null, channel, userToKick, comment ); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new KickCommand( - new FullNick( prefix ), - getParameter( params, 0 ), - getParameter( params, 1 ), - getParameter( params, 2 ) - ); - } - - public String getIrcIdentifier() - { - return "KICK"; - } - - public String renderParams() - { - return channel + " " + userKicked + " :" + comment; - } - - public String getChannel() - { - return channel; - } - - public FullNick getKicker() - { - return userKicker; - } - - public FullNick getKicked() - { - return userKicked; - } - - public String getComment() - { - return comment; - } - - public boolean kickedUs( ClientState state ) - { - return userKicked.equals( state.getNick() ); - } - - public boolean updateClientState( ClientState state ) - { - if( kickedUs( state ) ) - { - // We've been kicked. - //log.debug("KICK: We've been kicked " + channel); - state.removeChannel( channel ); - return true; - } - else - { - // Someone else was kicked. - //log.debug("KICK: " + userKicked.getNick() + " kicked " + channel); - // 1) Grab group - Channel channelObj = state.getChannel( channel ); - channelObj.removeMember( userKicked, this ); - return true; - } - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/MessageCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/MessageCommand.java deleted file mode 100644 index 3d66f7c21..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/MessageCommand.java +++ /dev/null @@ -1,127 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.util.FullNick; - - -/** - * Defines the PRIVMSG command. Messages can be sent to groups or to users. - */ -public class MessageCommand extends AbstractCommand -{ - - private FullNick from; - private String dest; - private String message; - - - /** Factory */ - public MessageCommand() - { - from = null; - dest = null; - message = null; - } - - /** - * Used to send a message. - * - * @param dest Target for message - * @param message Message to be sent - */ - public MessageCommand( String dest, String message ) - { - this( null, dest, message ); - } - - /** - * Used to send a message. - * - * @param dest Target for message - * @param message Message to be sent - */ - public MessageCommand( FullNick dest, String message ) - { - this( dest.getNick(), message ); - } - - public MessageCommand( FullNick source, String dest, String message ) - { - this.from = source; - this.dest = dest; - this.message = message; - } - - /** - * Parses a string and produces a formed command object, if it can. - * Should return null if it cannot form the command object. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - FullNick from; - if( prefix == null || prefix.trim().length() == 0 ) - { - from = null; - } - else - { - from = new FullNick( prefix ); - } - String dest = getParameter( params, 0 ); - String msg = getParameter( params, 1 ); - - if( CtcpMessage.isCtcpString( msg ) ) - { - return new CtcpMessage( from, dest, msg ); - } - - return new MessageCommand( from, dest, msg ); - } - - /** - * Returns the string IRC uses to identify this command. Examples: - * NICK, PING, KILL, 332 - */ - public String getIrcIdentifier() - { - return "PRIVMSG"; - } - - /** - * Renders the parameters of this command. - */ - public String renderParams() - { - return dest + " :" + message; - } - - public FullNick getSource() - { - return from; - } - - public String getDest() - { - return dest; - } - - public String getMessage() - { - return message; - } - - /** - * Returns true if the message is both private and for us. - * - * @param state Client state to compare with - * @return True or false if this is a private message to us - */ - public boolean isPrivateToUs( ClientState state ) - { - return state.getNick().equals( dest ); - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ModeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ModeCommand.java deleted file mode 100644 index b3c3e19ef..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/ModeCommand.java +++ /dev/null @@ -1,237 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.CommandRegister; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.Mode; -import f00f.net.irc.martyr.OutCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; -import java.util.logging.Logger; - -/** - * Defines MODE command. Since the MODE command is of two distinct - * types, this class is really more of a command mini-factory. It - * determines which type of command it is, either a UserModeCommand or - * a ChannelModeCommand. - * - */ -public class ModeCommand implements InCommand, OutCommand -{ - static Logger log = Logger.getLogger(ModeCommand.class.getName()); - - public static final String IDENTIFIER = "MODE"; - private String source; - - /** For use as a factory */ - public ModeCommand() - { - } - - public Iterator getAttributeKeys() - { - return new LinkedList().iterator(); - } - - public String getAttribute( String key ) - { - return null; - } - - public static void registerMode( Map modes, Mode mode ) - { - Character modeChar = mode.getChar(); - - if( modes.get( modeChar ) != null ) - { - log.severe("ModeCommand: Warning: Two modes with same letter: " + - modes.get( modeChar ) + " and " + mode); - } - - modes.put( modeChar, mode ); - } - - public State getState() - { - return State.REGISTERED; - } - - public void selfRegister( CommandRegister reg ) - { - reg.addCommand( IDENTIFIER, this ); - } - - public String getIrcIdentifier() - { - return IDENTIFIER; - } - - // Example - //
:repp_!bdamm@dammfine.com MODE #bytesex +oo z * repp_telnet
- public InCommand parse( String prefix, String identifier, String params ) - { - // there are two kinds of modes. Either a channel mode, or a user - // mode. We need to figure out which we are dealing with, and - // return that. - - // TODO: Research: Should we specify delimiters other than whitespace? - StringTokenizer tokens = new StringTokenizer( params ); - - String str = tokens.nextToken(); - - //log.debug("ModeCommand: Prefix: " + prefix + " str: " + str - // + " total: " + params); - - // Malformed command. - if( str == null ) - return null; - - // Should we check to see if the string is really a channel - // that we know about? - if( Channel.isChannel( str ) ) - { - return new ChannelModeCommand( prefix, str, tokens ); - } - else - { - return new UserModeCommand( prefix, str, tokens ); - } - } - - /** - * Should not be called, as ModeCommand doesn't actually represent a - * command. Use UserModeCommand or ChannelModeCommand instead. - */ - public String render() - { - throw new IllegalStateException("Don't try to send ModeCommand!"); - } - - public void setSourceString( String source ) - { - this.source = source; - } - - public String getSourceString() - { - return source; - } - - /** - * Does nothing, as this is a factory command. - */ - public boolean updateClientState( ClientState cs ) - { - // Nothing here, move on. - return false; - } - - public String toString() - { - return "ModeCommand"; - } - - /** Takes a mode string, such as: '+ooo A B C' or '+o A +o B' or even - * '+o-o A B' and returns a List containing Mode objects that - * correspond to the modes specified. - * - * @param modes is a Map of Character to Mode objects. - * @param tokens is the sequence of tokens making up the parameters of - * the command. - * @return List of modes - */ - public List parseModes( Map modes, StringTokenizer tokens ) - { - LinkedList results = new LinkedList(); - - while( true ) - { - if( tokens.hasMoreTokens() ) - { - parseOneModeSet( modes, tokens, results ); - } - else - { - return results; - } - } - } - - /** - * Parses one group of modes. '+ooo A B C' and not '+o A +o B'. It - * will parse the first group it finds and will ignore the rest. - * - * @param modes Map of character to Mode objects. - * @param tokens Sequence of tokens making up the parameters of the command. - * @param results List of Mode results to be filled in - */ - private void parseOneModeSet( Map modes, StringTokenizer tokens, List results ) - { - // A list of modes that we have. - LinkedList localModes = new LinkedList(); - - Mode.Sign sign = Mode.Sign.NOSIGN; - String chars = tokens.nextToken(); - - int stop = chars.length(); - for( int i = 0; i < stop; ++i ) - { - char lookingAt = chars.charAt( i ); - if( lookingAt == '+' ) - sign = Mode.Sign.POSITIVE; - else if( lookingAt == '-' ) - sign = Mode.Sign.NEGATIVE; - else if( lookingAt == ':' ) - // This is to get around a bug in some ircds - continue; - else - { - // A real mode character! - Mode mode = modes.get( lookingAt ); - if( mode == null ) - { - //TODO: Is there some way we can figure out if the mode - // we don't know anything about needs a parameter? - // Things get messy if it does need a parameter, and we - // don't eat the string. - //log.severe("ModeCommand: Unknown mode: " + lookingAt); - } - else - { - mode = mode.newInstance(); - mode.setSign( sign ); - localModes.add( mode ); - } - } - } - - // Now we know what modes are specified, and whether they are - // positive or negative. Now we need to fill in the parameters for - // any that require parameters, and place the results in the result - // list. - for (Mode localMode : localModes) { - /* - * What we do if the server doesn't pass us a parameter - * for a mode is rather undefined - except that we don't - * want to run off the end of the tokens. So we just - * ignore it. The problem is that we don't always know - * when a server is going to send us a parameter or not. - * We can only hope that servers don't send ambiguous - * masks followed by more modes instead of a parameter. - */ - if (localMode != null && localMode.requiresParam() && tokens.hasMoreTokens()) { - localMode.setParam(tokens.nextToken()); - } - - results.add(localMode); - } - } -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NamesCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NamesCommand.java deleted file mode 100644 index 6f0a9ed5d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NamesCommand.java +++ /dev/null @@ -1,77 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.OutCommand; - -import java.util.List; -import java.util.ArrayList; - -/** - * Defines the NAMES command, which is used to get the members of certain channels, or all of them. - * - * @author Daniel Henninger - */ -public class NamesCommand implements OutCommand -{ - - /* List of channels we will request membership of. */ - List channels = new ArrayList(); - - /** - * No parameter passed to the NAMES command represents a request for all channels. - */ - public NamesCommand() - { - // Nothing to do - } - - /** - * Request the membership of a single channel. - * - * @param channel Channel you want to request membership of. - */ - public NamesCommand(String channel) - { - this.channels.add(channel); - } - - /** - * Request the membership of multiple channels. - * - * @param channels List of channels you want to retrieve the membership list of. - */ - public NamesCommand(List channels) - { - this.channels.addAll(channels); - } - - /** - * @see f00f.net.irc.martyr.OutCommand#render() - */ - public String render() - { - String ret = getIrcIdentifier(); - if (channels.size() > 0) { - ret = ret + " "; - Boolean isFirst = true; - for (String channel : channels) { - if (isFirst) { - ret = ret + channel; - isFirst = false; - } - else { - ret = ret + "," + channel; - } - } - } - return ret; - } - - /** - * @see f00f.net.irc.martyr.Command#getIrcIdentifier() - */ - public String getIrcIdentifier() - { - return "NAMES"; - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NickCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NickCommand.java deleted file mode 100644 index 6cdcb0224..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NickCommand.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Original version: Ben Damm - * Changes by: Mog - * - added getOldNick - * */ -package f00f.net.irc.martyr.commands; - -import java.util.Enumeration; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.clientstate.Member; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Defines NICK command. - */ -public class NickCommand extends AbstractCommand -{ - - private FullNick oldNick; - private FullNick newNick; - - /** For use as a factory */ - public NickCommand() - { - this( null, null ); - } - - public NickCommand( FullNick oldNick, FullNick newNick ) - { - this.oldNick = oldNick; - this.newNick = newNick; - } - - public NickCommand( String newNick ) - { - this( null, new FullNick( newNick ) ); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NickCommand( new FullNick( prefix ), new FullNick ( getParameter( params, 0 ) ) ); - } - - public String getIrcIdentifier() - { - return "NICK"; - } - - public String renderParams() - { - return getNick(); - } - - public String getNick() - { - return newNick.getNick(); - } - - public String getOldNick() - { - return oldNick.getNick(); - } - - public boolean updateClientState( ClientState state ) - { - // Does this apply to us? - if( oldNick.equals( state.getNick() ) ) - { - state.setNick( newNick ); - return true; - } - else - { - // Ok, so we need to change someone's nick. - // This needs to occur for each member with that nick in each - // channel that we are in. Just use Member.setNick for each - // occurance. - // Note: I do not believe this code has received a vigorous - // test. - Enumeration channels = state.getChannels(); - while( channels.hasMoreElements() ) - { - Channel channel = (Channel)channels.nextElement(); - Member member = channel.findMember( oldNick.getNick() ); - if( member != null ) - member.setNick( newNick ); - } - } - return false; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NoticeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NoticeCommand.java deleted file mode 100644 index 958dcc44f..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/NoticeCommand.java +++ /dev/null @@ -1,129 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.util.FullNick; - - -/** - * Defines the NOTICE command. - */ -public class NoticeCommand extends AbstractCommand -{ - - private FullNick from; - private String dest; - private String notice; - - /** Factory */ - public NoticeCommand() - { - from = null; - dest = null; - notice = null; - } - - public NoticeCommand( String notice ) - { - this.notice = notice; - } - - public NoticeCommand( String dest, String notice ) - { - this(null, dest, notice); - } - - public NoticeCommand( FullNick dest, String notice ) - { - this(dest.getNick(), notice); - } - - public NoticeCommand( FullNick source, String dest, String notice ) { - this.from = source; - this.dest = dest; - this.notice = notice; - } - - public State getState() - { - return State.UNKNOWN; - } - - /** - * Parses a string and produces a formed command object, if it can. - * Should return null if it cannot form the command object. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - FullNick from; - if( prefix == null || prefix.trim().length() == 0 ) - { - from = null; - } - else - { - from = new FullNick( prefix ); - } - String dest = getParameter( params, 0 ); - String msg = getParameter( params, 1 ); - - if( CtcpNotice.isCtcpString( msg ) ) - { - return new CtcpNotice( from, dest, msg ); - } - - return new NoticeCommand( from, dest, msg ); - } - - /** - * Returns the string IRC uses to identify this command. Examples: - * NICK, PING, KILL, 332 - */ - public String getIrcIdentifier() - { - return "NOTICE"; - } - - /** - * Renders the parameters of this command. - */ - public String renderParams() - { - if (dest != null) { - return dest + " :" + notice; - } - else { - return ":" + notice; - } - } - - public FullNick getFrom() - { - return from; - } - - public String getDest() - { - return dest; - } - - public String getNotice() - { - return notice; - } - - /** - * Returns true if the message is both private and for us. - * - * @param state Client state to compare with - * @return True or false if this is a private message to us - */ - public boolean isPrivateToUs( ClientState state ) - { - return state.getNick().equals( dest ); - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PartCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PartCommand.java deleted file mode 100644 index b27ed6dd2..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PartCommand.java +++ /dev/null @@ -1,126 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.util.FullNick; - -/** - *

Defines PART command. If the part command is from us, we should - * remove that channel from the list of channels. If the part command - * is from someone else, we should remove that user from the list of - * users for that channel. - */ - -public class PartCommand extends AbstractCommand -{ - - private String reason; - private String channel; - private FullNick user; - - /** For use as a factory */ - public PartCommand() - { - this( null, null, null ); - } - - /** - * For use as an incoming command. - * - * @param user User that is parting - * @param channel Channel that the user is parting from - * @param reason Reason for part - */ - public PartCommand( FullNick user, String channel, String reason ) - { - this.user = user; - this.reason = reason; - this.channel = channel; - } - - /** - * For use as an outgoing command. - * - * @param channel Channel that we are parting from - * @param reason Reason we are parting - */ - public PartCommand( String channel, String reason ) - { - this( null, channel, reason ); - } - - /** - * For use as an outgoing command. Part with no reason. - * - * @param channel Channel that we are parting from - */ - public PartCommand( String channel ) - { - this( null, channel, null ); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new PartCommand( new FullNick( prefix ), getParameter( params, 0 ), getParameter( params, 1 ) ); - } - - public String getIrcIdentifier() - { - return "PART"; - } - - public String renderParams() - { - if( reason != null ) - return channel + " :" + reason; - else - return channel; - } - - public String getReason() - { - return reason; - } - - public String getChannel() - { - return channel; - } - - public FullNick getUser() - { - return user; - } - - /** Takes client state action. If we are parting, then remove that - * channel from our list of channels. If someone else is parting, - * remove them from the channel they are parting from. - */ - public boolean updateClientState( ClientState state ) - { - // We parted - if( user.equals( state.getNick() ) ) - { - state.removeChannel( channel ); - return true; - } - else - { - // Someone else parted. - - // 1) Grab channel - Channel chanObj = state.getChannel( channel ); - - // 2) Remove user - chanObj.removeMember( user, this ); - return true; - } - - } - -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PassCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PassCommand.java deleted file mode 100644 index da1e63cd5..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PassCommand.java +++ /dev/null @@ -1,33 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.OutCommand; - -/** - * Defines PASS command, optional part of the handshake to register on the network. - * @author Daniel Henninger - */ -public class PassCommand implements OutCommand -{ - private String pass; - - public static final String IDENTIFIER = "PASS"; - - /** - * @param pass the password for the user who is authenticating - * */ - public PassCommand(String pass) - { - this.pass = pass; - } - - public String render() - { - return IDENTIFIER + " " + pass; - } - - public String getIrcIdentifier() - { - return IDENTIFIER; - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PingCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PingCommand.java deleted file mode 100644 index 01c68cb90..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PingCommand.java +++ /dev/null @@ -1,67 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; - - -/** - * Defines the PING command. At this point, PINGs only come in from - * the server, so all we need to do is capture the parameters. - */ -public class PingCommand extends AbstractCommand -{ - - private String pingSource; - - /** Factory */ - public PingCommand() - { - pingSource = null; - } - - public PingCommand( String source ) - { - pingSource = source; - } - - public State getState() - { - return State.UNKNOWN; - } - - /** - * Parses a string and produces a formed command object, if it can. - * Should return null if it cannot form the command object. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - String str = getParameter( params, 0 ); - return new PingCommand( str ); - } - - /** - * Returns the string IRC uses to identify this command. Examples: - * NICK, PING, KILL, 332 - */ - public String getIrcIdentifier() - { - return "PING"; - } - - /** - * Renders the parameters of this command. - */ - public String renderParams() - { - return ":" + pingSource; - } - - // ===== Ping-specific methods ======================================= - public String getPingSource() - { - return pingSource; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PongCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PongCommand.java deleted file mode 100644 index bfd22531a..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/PongCommand.java +++ /dev/null @@ -1,39 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; - - -/** - * Defines the PONG command. At this point, PONGs can only be sent to - * the server, so all we need to do is provide render(). - */ -public class PongCommand extends PingCommand -{ - - public PongCommand( String dest ) - { - super( dest ); - } - - /** - * PONG shouldn't be sent to us. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - throw new UnsupportedOperationException("PONG is not an incommand."); - } - - public String getIrcIdentifier() - { - return "PONG"; - } - - // ===== Pong-specific methods ======================================= - public String getPongDest() - { - return getPingSource(); - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/QuitCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/QuitCommand.java deleted file mode 100644 index e12a2520d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/QuitCommand.java +++ /dev/null @@ -1,132 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.Enumeration; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.util.FullNick; - -/** - *

Defines QUIT command. The QUIT command asks the irc server to - * disconnect us, and we can optionally give a reason. The QUIT - * command is also received by us if someone on a channel we are on - * quits.

- * - *

What should be done to signal to the framework that the - * disconnection that should come from the server is legit, and we - * shouldn't try to re-connecet? For now it will be assumed that the - * user of the framework will signal all the appropriate classes that - * a legit disconnection will happen (ie AutoRegister which will try - * to re-connect otherwise).

- */ -public class QuitCommand extends AbstractCommand -{ - //static Logger log = Logger.getLogger(QuitCommand.class); - - private String reason; - private FullNick user; - - /** For use as a factory */ - public QuitCommand() - { - this( null, null ); - } - - /** - * For use as an incoming command. - * - * @param user User that has quit - * @param reason Specified reason for quitting - */ - public QuitCommand( FullNick user, String reason ) - { - this.user = user; - this.reason = reason; - } - - /** - * For use as an outgoing command. - * - * @param reason Specified reason for quitting - */ - public QuitCommand( String reason ) - { - this( null, reason ); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new QuitCommand( new FullNick( prefix ), getParameter( params, 0 ) ); - } - - public String getIrcIdentifier() - { - return "QUIT"; - } - - public String renderParams() - { - return ":" + reason; - } - - public String getReason() - { - return reason; - } - - public FullNick getUser() - { - return user; - } - - /** - * Returns true if we are the ones quitting. - * - * @param state Client state we are checking against - * @return True or false if the quit is us quitting - */ - public boolean isOurQuit( ClientState state ) - { - return user.equals( state.getNick() ); - } - - /** If we are quitting, we won't be worrying about our client state. - * If someone else is leaving, then remove them from all the groups - * they are in. - */ - public boolean updateClientState( ClientState state ) - { - //log.debug( "Nick: " + state.getNick().toString() ); - if( isOurQuit(state) ) - { - // We've quit - //log.debug("QUIT: We've quit: " + reason); - - // What should we do with the client state here? - return true; - } - else - { - // Someone else quit. We need to remove them from each group - // they are in. - //log.debug("QUIT: " + user + " quit: " + reason); - - // 1) Grab channels - Enumeration channelNames = state.getChannelNames(); - while( channelNames.hasMoreElements() ) - { - String chanName = channelNames.nextElement().toString(); - - // 2) Remove from group. - Channel channelObj = state.getChannel( chanName); - channelObj.removeMember( user, this ); - } - - return true; - } - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/RawCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/RawCommand.java deleted file mode 100644 index b7375e92f..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/RawCommand.java +++ /dev/null @@ -1,58 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.OutCommand; - -public class RawCommand implements OutCommand -{ - - private String sourceString; - private String ident; - - /** - * Tries to use the first "word" in the command as the identifier. - * Using this constructor is not recommended. - * - * @param raw Raw command to send to server - */ - public RawCommand( String raw ) - { - sourceString = raw; - StringTokenizer tokens = new StringTokenizer( raw ); - ident = tokens.nextToken(); - } - - /** - * The rendered command will be identifier + " " + - * parameters. This constructure simply allows a correct - * response to the getIrcIdentifier method. - * - * @param identifier Command identifier - * @param parameters Parameters to pass - */ - public RawCommand( String identifier, String parameters ) - { - ident = identifier; - sourceString = ident + " " + parameters; - } - - /** - * Returns the identifier, if supplied, or null. - */ - public String getIrcIdentifier() - { - return ident; - } - - /** - * Simply returns the string given in the constructor. - */ - public String render() - { - return sourceString; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/TopicCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/TopicCommand.java deleted file mode 100644 index 42e3d0421..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/TopicCommand.java +++ /dev/null @@ -1,80 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.Date; - -import f00f.net.irc.martyr.CommandRegister; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; - -public class TopicCommand extends AbstractCommand -{ - //static Logger log = Logger.getLogger(TopicCommand.class); - - private String channel; - private String topic; - - public static final String IDENTIFIER_PRIMARY = "TOPIC"; - public static final String IDENTIFIER_SECONDARY = "332"; - - public TopicCommand() - { - this( null, null ); - } - - public TopicCommand( String channel, String topic ) - { - this.channel = channel; - this.topic = topic; - } - - public String getIrcIdentifier() - { - // - // This command uses "TOPIC" on outgoing, so that is why we use - // "TOPIC" here instead of "332". - // - return IDENTIFIER_PRIMARY; - } - - public void selfRegister( CommandRegister commandRegister ) - { - commandRegister.addCommand( IDENTIFIER_PRIMARY, this ); - commandRegister.addCommand( IDENTIFIER_SECONDARY, this ); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - // when the command is used as a reply, the nick is parameter 0. - if( identifier.equals( IDENTIFIER_SECONDARY ) ) - return new TopicCommand( getParameter(params, 1), getParameter(params, 2) ); - else - return new TopicCommand( getParameter(params, 0), getParameter(params, 1) ); - } - - public String renderParams() - { - return getChannel() + " :" + getTopic(); - } - - public String getTopic() - { - return topic; - } - - public String getChannel() - { - return channel; - } - - public boolean updateClientState( ClientState state ) - { - //log.debug("Topic: Channel: " + channel); - Channel chan = state.getChannel( channel ); - chan.setTopic( topic ); - chan.setTopicDate( new Date() ); - return true; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UnknownCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UnknownCommand.java deleted file mode 100644 index 6ecd4bc4d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UnknownCommand.java +++ /dev/null @@ -1,38 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; - - -/** - * Some unknown command, for which there is no factory. This is a - * special case command, created by IRCConnection if it can't find a - * proper command object. - */ -public class UnknownCommand extends AbstractInCommand -{ - - public State getState() - { - return State.UNKNOWN; - } - - /** - * Never parsed. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - throw new UnsupportedOperationException("UnknownCommand does no parsing."); - } - - /** - * Unknown, so we don't know what the identifier is ahead of time. - */ - public String getIrcIdentifier() - { - return null; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserCommand.java deleted file mode 100644 index ac7796f7c..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.IRCConnection; -import f00f.net.irc.martyr.OutCommand; -/** - * Defines USER command, part of the handshake to register on the - * network. - */ -public class UserCommand implements OutCommand -{ - - private String name; - private String user; - private String someA; // Might be a mode on some networks - private String someB; // might be ignored - - public static final String IDENTIFIER = "USER"; - - /** - * @param user the login name on the computer the client is on - * @param name the purported full name of the user, can be anything. - * @param connection the connection the user command is affiliated with - * */ - public UserCommand( String user, String name, IRCConnection connection ) - { - this.name = name; - this.user = user; - //localhost = connection.getLocalhost(); - //remotehost = connection.getRemotehost(); - someA = "0"; // Can be 0|4|8, with 4=+w, 8=+i - someB = connection.getRemotehost(); // ignored, apparently - } - - public String render() - { - return IDENTIFIER + " " + user + " " + someA + " " + someB + " :" + name; - } - - public String getIrcIdentifier() - { - return IDENTIFIER; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserModeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserModeCommand.java deleted file mode 100644 index 1190ed64a..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/UserModeCommand.java +++ /dev/null @@ -1,99 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import java.util.HashMap; -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.Mode; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.modes.user.InvisibleMode; -import f00f.net.irc.martyr.util.FullNick; -import java.util.logging.Logger; - -/** - * Defines a user MODE command. - */ -public class UserModeCommand extends ModeCommand -{ - static Logger log = Logger.getLogger(ModeCommand.class.getName()); - - private FullNick user; - private FullNick sender; - //private List modes; - - private static HashMap modeTypes; - - public UserModeCommand( String prefix, String userStr, StringTokenizer tokens ) - { -// System.out.println( prefix ); - sender = new FullNick( prefix ); - user = new FullNick( userStr ); - - if( !sender.equals( user ) ) - { - log.severe("UserModeCommand: Odd: mode change for a user that isn't us."); - return; - } - - makeModeTypes(); - - //modes = parseModes( modeTypes, tokens ); - -// System.out.println( modes ); - } - - private void makeModeTypes() - { - if( modeTypes == null ) - { - modeTypes = new HashMap(); - - // Add new mode types here - registerMode( modeTypes, new InvisibleMode() ); - } - } - - - /** - * Should not be called, as ModeCommand does the parsing and instantiation - * of this class. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - throw new IllegalStateException( "Don't call this method!" ); - } - - public String render() - { - throw new UnsupportedOperationException("Can't send user modes, yet." ); - } - - public FullNick getUser() - { - return user; - } - - public FullNick getSender() { - return sender; - } - - { - //log.debug("TODO: UserModeCommand: Can't send"); - //log.debug("TODO: UserModeCommand: Does not update client state"); - } - - public boolean updateClientState( ClientState state ) - { - // TODO implement - return false; - } - - public String toString() - { - return "UserModeCommand"; - } - - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WelcomeCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WelcomeCommand.java deleted file mode 100644 index ecbe9b1ac..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WelcomeCommand.java +++ /dev/null @@ -1,125 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.CommandRegister; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.util.FullNick; -import f00f.net.irc.martyr.util.ParameterIterator; -import java.util.logging.Logger; - - -/** - * Defines the commands that a server issues to welcome us. These are - * identified with 001, 002... etc. These commands are only received - * after we register, unlike the NOTICE command. - */ -public class WelcomeCommand extends AbstractInCommand -{ - static Logger log = Logger.getLogger(WelcomeCommand.class.getName()); - - private String notice; - private String nick; - - /** Factory */ - public WelcomeCommand() - { - this( null, null ); - } - - /** - * Used by parse to create an instance of WelcomeCommand. - * - * @param nick Nick that send the welcome - * @param notice Notice that was sent - * */ - public WelcomeCommand( String nick, String notice ) - { - this.notice = notice; - this.nick = nick; - //log.debug("WelcomeCommand: Nick is: `" + nick + "'"); - //log.debug("WelcomeCommand: Notice is: `"+notice+"'"); - } - - /** - * Parses a string and produces a formed command object, if it can. - * Should return null if it cannot form the command object. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - ParameterIterator pi = new ParameterIterator( params ); - String nick = pi.next().toString(); - String notice; - if( pi.hasNext() ) - { - // We are looking at a "nick :msg" pair - notice = pi.next().toString(); - } - else - { - // There is only one parameter, a notice. - notice = nick; - nick = null; - } - if( pi.hasNext() ) - { - //log.severe("WelcomeCommand: More than two parameters, confused."); - } - - - //String str = getParameter( params, 0 ); - // - return new WelcomeCommand( nick, notice ); - } - - /** - * Sets the nick of the client state, if there is one included with - * this command. - */ - public boolean updateClientState( ClientState state ) - { - //log.debug("WelcomeCommand: updated client state with: " + new FullNick( nick )); - state.setNick( new FullNick( nick ) ); - - return true; - } - - /** - * Returns the string IRC uses to identify this command. Examples: - * NICK, PING, KILL, 332. In our case, there is no one thing. - */ - public String getIrcIdentifier() - { - return "001"; - } - - public void selfRegister( CommandRegister commandRegister ) - { - commandRegister.addCommand( "001", this ); - commandRegister.addCommand( "002", this ); - commandRegister.addCommand( "003", this ); - commandRegister.addCommand( "004", this ); - commandRegister.addCommand( "005", this ); - } - - public String getNotice() - { - return notice; - } - - /** - * @return the nick received with this command, or null if there isn't - * one. - * */ - public String getNick() - { - return nick; - } - - public String toString() - { - return "WelcomeCommand"; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WhoisCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WhoisCommand.java deleted file mode 100644 index 1c5dea618..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/WhoisCommand.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.commands; - -import f00f.net.irc.martyr.OutCommand; - -/** - * Implements a WHOIS command, to query details about a user. - * - */ -public class WhoisCommand implements OutCommand -{ - private static final String WHOIS = "WHOIS"; - - private String target; - - /** - * @param target the nick or mask that you wish to know about. - */ - public WhoisCommand( String target ) - { - this.target = target; - } - - /** - * @return "WHOIS" - */ - public String getIrcIdentifier() - { - return WHOIS; - } - - /** - * Simply returns the string given in the constructor. - */ - public String render() - { - return WHOIS + " " + target; - } -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/AlreadyRegisteredError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/AlreadyRegisteredError.java deleted file mode 100644 index 736b5ebf6..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/AlreadyRegisteredError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 462 ERR_ALREADYREGISTERED - * :You may not reregister - * Returned by the server to any link which tries to change part of the registered details (such as - * password or user details from second USER message). - */ -public class AlreadyRegisteredError extends GenericError -{ - private String errorMessage; - - public AlreadyRegisteredError() - { - } - - public AlreadyRegisteredError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "462"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new AlreadyRegisteredError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CannotSendToChanError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CannotSendToChanError.java deleted file mode 100644 index 93793c89a..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CannotSendToChanError.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 404 ERR_CANNOTSENDTOCHAN - * <channel name> :Cannot send to channel - * Sent to a user who is either (a) not on a channel which is mode +n or (b) not a chanop (or mode +v) - * on a channel which has mode +m set and is trying to send a PRIVMSG message to that channel. - */ -public class CannotSendToChanError extends GenericError -{ - private String channel; - private String errorMessage; - - public CannotSendToChanError() - { - } - - public CannotSendToChanError(String channel, String errorMessage) - { - this.channel = channel; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "404"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new CannotSendToChanError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getChannel() - { - return channel; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CantKillServerError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CantKillServerError.java deleted file mode 100644 index 246bcbbe7..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/CantKillServerError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 483 ERR_CANTKILLSERVER - * :You can't kill a server! - * Any attempts to use the KILL command on a server are to be refused and this - * error returned directly to the client. - */ -public class CantKillServerError extends GenericError -{ - private String errorMessage; - - public CantKillServerError() - { - } - - public CantKillServerError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "483"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new CantKillServerError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChanOPrivsNeededError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChanOPrivsNeededError.java deleted file mode 100644 index 366dc2b10..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChanOPrivsNeededError.java +++ /dev/null @@ -1,48 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 482 ERR_CHANOPRIVSNEEDED - * <channel> :You're not channel operator - * Any command requiring 'chanop' privileges (such as MODE messages) must return - * this error if the client making the attempt is not a chanop on the specified - * channel. - */ -public class ChanOPrivsNeededError extends GenericError -{ - private String channel; - private String errorMessage; - - public ChanOPrivsNeededError() - { - } - - public ChanOPrivsNeededError(String channel, String errorMessage) - { - this.channel = channel; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "482"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new ChanOPrivsNeededError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getChannel() - { - return channel; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelBannedError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelBannedError.java deleted file mode 100644 index 7e3411b70..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelBannedError.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ChannelBannedError.java - * - * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * See: http://www.fsf.org/copyleft/lesser.txt - */ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 474 ERR_BANNEDFROMCHAN - * <channel> :Cannot join channel (+b) - * @author Morgan Christiansson - * @version $Id: ChannelBannedError.java 85 2007-08-02 18:26:59Z jadestorm $ - * TODO: Should er rename this to BannedFromChanError to match others? - */ -public class ChannelBannedError extends GenericJoinError { - public ChannelBannedError() - { - // This one's for registering. - } - - protected ChannelBannedError( String chan, String comment ) - { - super(chan, comment); - } - - public String getIrcIdentifier() - { - return "474"; - } - - protected InCommand create( String channel, String comment) - { - return new ChannelBannedError( channel, comment ); - } -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelInviteOnlyError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelInviteOnlyError.java deleted file mode 100644 index af6322b61..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelInviteOnlyError.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ChannelInviteOnlyError.java - * - * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * See: http://www.fsf.org/copyleft/lesser.txt - */ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -/** - * Code: 473 ERR_INVITEONLYCHAN - * <channel> :Cannot join channel (+i) - * @version $Id: ChannelInviteOnlyError.java 85 2007-08-02 18:26:59Z jadestorm $ - * TODO: Should we rename this to InviteOnlyChanError to match others? - */ -public class ChannelInviteOnlyError extends GenericJoinError -{ - public ChannelInviteOnlyError() - { - // This one's for registering. - } - - protected ChannelInviteOnlyError( String chan, String comment ) - { - super(chan, comment); - } - - public String getIrcIdentifier() - { - return "473"; - } - - protected InCommand create(String channel, String comment) - { - return new ChannelInviteOnlyError( channel, comment ); - } -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelLimitError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelLimitError.java deleted file mode 100644 index 8e7174286..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelLimitError.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ChannelLimitError.java - * - * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * See: http://www.fsf.org/copyleft/lesser.txt - */ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 471 ERR_CHANNELISFULL - * <channel> :Cannot join channel (+l) - * @author Morgan Christiansson - * @version $Id: ChannelLimitError.java 85 2007-08-02 18:26:59Z jadestorm $ - * TODO: Rename to ChannelIsFullError to match style of others? - */ -public class ChannelLimitError extends GenericJoinError -{ - public ChannelLimitError() - { - // This one's for registering. - } - - protected ChannelLimitError( String chan, String comment ) - { - super(chan, comment); - } - - public String getIrcIdentifier() - { - return "471"; - } - - protected InCommand create(String channel, String comment) - { - return new ChannelLimitError( channel, comment ); - } -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelWrongKeyError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelWrongKeyError.java deleted file mode 100644 index 099352f9b..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ChannelWrongKeyError.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ChannelWrongKeyError.java - * - * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * See: http://www.fsf.org/copyleft/lesser.txt - */ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 475 ERR_BADCHANNELKEY - * <channel> :Cannot join channel (+k) - * @author Morgan Christiansson - * @version $Id: ChannelWrongKeyError.java 85 2007-08-02 18:26:59Z jadestorm $ - * TODO: Should we rename to BadChannelKeyError to match others? - */ -public class ChannelWrongKeyError extends GenericJoinError -{ - public ChannelWrongKeyError() - { - super(); - } - - protected ChannelWrongKeyError(String chan, String comment) - { - super(chan, comment); - } - - public String getIrcIdentifier() - { - return "475"; - } - - protected InCommand create(String channel, String comment) { - return new ChannelWrongKeyError(channel, comment); - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ErroneusNicknameError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ErroneusNicknameError.java deleted file mode 100644 index 4b0bb6bbe..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/ErroneusNicknameError.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Code: 432 ERR_ERRONEUSNICKNAME - * <nick> :Erroneus nickname - * Returned after receiving a NICK message which contains characters which do not fall in the defined set. - */ -public class ErroneusNicknameError extends GenericError -{ - private FullNick nick; - private String errorMessage; - - public ErroneusNicknameError() - { - } - - public ErroneusNicknameError(FullNick nick, String errorMessage) - { - this.nick = nick; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "432"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new ErroneusNicknameError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); - } - - public FullNick getNick() - { - return nick; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/FileErrorError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/FileErrorError.java deleted file mode 100644 index a41205c7f..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/FileErrorError.java +++ /dev/null @@ -1,39 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 424 ERR_FILEERROR - * :File error doing <file op> on <file> - * Generic error message used to report a failed file operation during the processing of a message. - */ -public class FileErrorError extends GenericError -{ - private String errorMessage; - - public FileErrorError() - { - } - - public FileErrorError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "424"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new FileErrorError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericError.java deleted file mode 100644 index 5e89fbfd0..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericError.java +++ /dev/null @@ -1,14 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.commands.AbstractInCommand; - -/** - * Defines what an error is. All errors are commands. - */ -public abstract class GenericError extends AbstractInCommand -{ - -} - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericJoinError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericJoinError.java deleted file mode 100644 index dfabcd3ef..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/GenericJoinError.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * GenericJoinError.java - * - * Copyright (C) 2000, 2001, 2002, 2003 Ben Damm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * See: http://www.fsf.org/copyleft/lesser.txt - */ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.util.ParameterIterator; - -/** - * @author Morgan Christiansson - * @version $Id: GenericJoinError.java 31 2004-04-01 22:02:33Z bdamm $ - */ -public abstract class GenericJoinError extends GenericError { - private String channel; - private String comment; - - public GenericJoinError() { - } - - protected GenericJoinError(String chan, String comment) - { - this.channel = chan; - this.comment = comment; - } - - protected abstract InCommand create(String channel, String comment); - - public String getChannel() - { - return channel; - } - - public String getComment() - { - return comment; - } - - public State getState() { - return State.UNKNOWN; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - ParameterIterator pI = new ParameterIterator( params ); - - pI.next(); // We know what our name is. - String channel = (String)pI.next(); - String comment = (String)pI.next(); - - return create( channel, comment ); - } -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/KeySetError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/KeySetError.java deleted file mode 100644 index 0d938263b..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/KeySetError.java +++ /dev/null @@ -1,45 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 467 ERR_KEYSEY - * <channel> :Channel key already set - */ -public class KeySetError extends GenericError -{ - private String channel; - private String errorMessage; - - public KeySetError() - { - } - - public KeySetError(String channel, String errorMessage) - { - this.channel = channel; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "467"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new KeySetError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getChannel() - { - return channel; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/LoadTooHighError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/LoadTooHighError.java deleted file mode 100644 index d6d4411b0..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/LoadTooHighError.java +++ /dev/null @@ -1,49 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; - -public class LoadTooHighError extends GenericError -{ - private FullNick nick; - private String command; - private String errorMessage; - - public LoadTooHighError() - { - } - - public LoadTooHighError(FullNick nick, String command, String errorMessage) - { - this.nick = nick; - this.command = command; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "263"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new LoadTooHighError(new FullNick(getParameter(params, 1)), getParameter(params, 2), getParameter(params, 3)); - } - - public FullNick getNick() - { - return nick; - } - - public String getCommand() - { - return command; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NeedMoreParamsError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NeedMoreParamsError.java deleted file mode 100644 index fa80c4dd6..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NeedMoreParamsError.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 461 ERR_NEEDMOREPARAMS - * <command> :Not enough parameters - * Returned by the server by numerous commands to indicate to the client that it didn't - * supply enough parameters. - */ -public class NeedMoreParamsError extends GenericError -{ - private String command; - private String errorMessage; - - public NeedMoreParamsError() - { - } - - public NeedMoreParamsError(String command, String errorMessage) - { - this.command = command; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "461"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NeedMoreParamsError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getCommand() - { - return command; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickCollisionError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickCollisionError.java deleted file mode 100644 index bf098196c..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickCollisionError.java +++ /dev/null @@ -1,48 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Code: 436 ERR_NICKCOLLISION - * <nick> :Nickname collision KILL - * Returned by a server to a client when it detects a nickname collision (registered of a NICK that - * already exists by another server). - */ -public class NickCollisionError extends GenericError -{ - private FullNick nick; - private String errorMessage; - - public NickCollisionError() - { - } - - public NickCollisionError(FullNick nick, String errorMessage) - { - this.nick = nick; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "436"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NickCollisionError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); - } - - public FullNick getNick() - { - return nick; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickInUseError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickInUseError.java deleted file mode 100644 index 93e37b4a4..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NickInUseError.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Original version: Ben Damm - * Changes by: Mog - * - Retains the nick that is in use - * */ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Code: 433 ERR_ERRONEUSNICKNAME - * <nick> :Nickname is already in use - * Returned when a NICK message is processed that result in an attempt to change - * to a currently existing nickname. - * TODO: Should we rename this to NicknameInUseError for consistency with rest of errors/matching RFC? - */ -public class NickInUseError extends GenericError -{ - private FullNick _nick; - String errorMessage; - - public NickInUseError() - { - _nick = null; - } - public NickInUseError(FullNick nick, String errorMessage) - { - _nick = nick; - this.errorMessage = errorMessage; - } - - public State getState() - { - return State.UNKNOWN; - } - - public String getIrcIdentifier() - { - return "433"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NickInUseError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); - } - - /** - * @return The nick in use. - */ - public FullNick getNick() - { - return _nick; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoAdminInfoError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoAdminInfoError.java deleted file mode 100644 index 10b14938b..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoAdminInfoError.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 423 ERR_NOADMININFO - * <server name> :No administrative info available - * Returned by a server in response to an ADMIN message when there is an error in finding the - * appropriate information. - */ -public class NoAdminInfoError extends GenericError -{ - private String server; - private String errorMessage; - - public NoAdminInfoError() - { - } - - public NoAdminInfoError(String server, String errorMessage) - { - this.server = server; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "423"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoAdminInfoError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getServer() - { - return server; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoLoginError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoLoginError.java deleted file mode 100644 index 12b2e39f3..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoLoginError.java +++ /dev/null @@ -1,48 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Code: 444 ERR_NOLOGIN - * <user> :User not logged in - * Returned by the summon after a SUMMON command for a user was unable to be performed - * since they were not logged in. - */ -public class NoLoginError extends GenericError -{ - private FullNick nick; - private String errorMessage; - - public NoLoginError() - { - } - - public NoLoginError(FullNick nick, String errorMessage) - { - this.nick = nick; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "444"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoLoginError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); - } - - public FullNick getNick() - { - return nick; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoMotdError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoMotdError.java deleted file mode 100644 index 0f157a33f..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoMotdError.java +++ /dev/null @@ -1,39 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 422 ERR_NOMOTD - * :MOTD File is missing - * Server's MOTD file could not be opened by the server. - */ -public class NoMotdError extends GenericError -{ - private String errorMessage; - - public NoMotdError() - { - } - - public NoMotdError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "422"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoMotdError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoNicknameGivenError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoNicknameGivenError.java deleted file mode 100644 index 7e2502d88..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoNicknameGivenError.java +++ /dev/null @@ -1,39 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 431 ERR_NONICKNAMEGIVEN - * :No nickname given - * Returned when a nickname parameter expected for a command and isn't found. - */ -public class NoNicknameGivenError extends GenericError -{ - private String errorMessage; - - public NoNicknameGivenError() - { - } - - public NoNicknameGivenError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "431"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoNicknameGivenError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOperHostError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOperHostError.java deleted file mode 100644 index 5ab026987..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOperHostError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 491 ERR_NOOPERHOST - * :No O-lines for your host - * If a client sends an OPER message and the server has not been configured to allow - * connections from the client's host as an operator, this error must be returned. - */ -public class NoOperHostError extends GenericError -{ - private String errorMessage; - - public NoOperHostError() - { - } - - public NoOperHostError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "491"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoOperHostError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOriginError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOriginError.java deleted file mode 100644 index 3ed8542fb..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoOriginError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 409 ERR_NOORIGIN - * :No origin specified - * PING or PONG message missing the originator parameter which is required since these commands must - * work without valid prefixes. - */ -public class NoOriginError extends GenericError -{ - private String errorMessage; - - public NoOriginError() - { - } - - public NoOriginError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "409"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoOriginError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPermForHostError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPermForHostError.java deleted file mode 100644 index 2cf22c211..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPermForHostError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 463 ERR_NOPERMFORHOST - * :Your host isn't among the privileged - * Returned to a client which attempts to register with a server which does not been setup to allow - * connections from the host the attempted connection is tried. - */ -public class NoPermForHostError extends GenericError -{ - private String errorMessage; - - public NoPermForHostError() - { - } - - public NoPermForHostError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "463"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoPermForHostError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPrivilegesError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPrivilegesError.java deleted file mode 100644 index d94df8172..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoPrivilegesError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 481 ERR_NOPRIVILEGES - * :Permission Denied- You're not an IRC operator - * Any command requiring operator privileges to operate must return this error to - * indicate the attempt was unsuccessful. - */ -public class NoPrivilegesError extends GenericError -{ - private String errorMessage; - - public NoPrivilegesError() - { - } - - public NoPrivilegesError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "481"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoPrivilegesError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoRecipientError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoRecipientError.java deleted file mode 100644 index e86cefc6c..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoRecipientError.java +++ /dev/null @@ -1,38 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 411 ERR_NORECIPIENT - * :No recipient given (<command>) - */ -public class NoRecipientError extends GenericError -{ - private String errorMessage; - - public NoRecipientError() - { - } - - public NoRecipientError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "411"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoRecipientError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchChannelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchChannelError.java deleted file mode 100644 index bf8b3910d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchChannelError.java +++ /dev/null @@ -1,46 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 403 ERR_NOSUCHCHANNEL - * <channel name> :No such channel - * Used to indicate the given channel name is invalid. - */ -public class NoSuchChannelError extends GenericError -{ - private String channel; - private String errorMessage; - - public NoSuchChannelError() - { - } - - public NoSuchChannelError(String channel, String errorMessage) - { - this.channel = channel; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "403"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoSuchChannelError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getChannel() - { - return channel; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchNickError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchNickError.java deleted file mode 100644 index 664a2c9d0..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchNickError.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Code: 401 ERR_NOSUCHNICK - * <nickname> :No such nick/channel - * Used to indicated the nickname parameter supplied to a command is currently unused. - */ -public class NoSuchNickError extends GenericError -{ - private FullNick nick; - private String errorMessage; - - public NoSuchNickError() - { - } - - public NoSuchNickError(FullNick nick, String errorMessage) - { - this.nick = nick; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "401"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoSuchNickError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); - } - - public FullNick getNick() - { - return nick; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchServerError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchServerError.java deleted file mode 100644 index cdb0dee90..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoSuchServerError.java +++ /dev/null @@ -1,46 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 402 ERR_NOSUCHSERVER - * <server name> :No such server - * Used to indicate the server name given currently doesn't exist. - */ -public class NoSuchServerError extends GenericError -{ - private String server; - private String errorMessage; - - public NoSuchServerError() - { - } - - public NoSuchServerError(String server, String errorMessage) - { - this.server = server; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "402"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoSuchServerError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getServer() - { - return server; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTextToSendError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTextToSendError.java deleted file mode 100644 index 6e0176295..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTextToSendError.java +++ /dev/null @@ -1,41 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 412 ERR_NOTEXTTOSEND - * :No text to send - * 412 - 414 are returned by PRIVMSG to indicate that the message wasn't delivered for some reason. - * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that are returned when an invalid use of - * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. - */ -public class NoTextToSendError extends GenericError -{ - private String errorMessage; - - public NoTextToSendError() - { - } - - public NoTextToSendError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "412"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoTextToSendError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTopLevelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTopLevelError.java deleted file mode 100644 index 4810ab8a1..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NoTopLevelError.java +++ /dev/null @@ -1,48 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 413 ERR_NOTOPLEVEL - * <mask> :No toplevel domain specified - * 412 - 414 are returned by PRIVMSG to indicate that the message wasn't delivered for some reason. - * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that are returned when an invalid use of - * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. - */ -public class NoTopLevelError extends GenericError -{ - private String mask; - private String errorMessage; - - public NoTopLevelError() - { - } - - public NoTopLevelError(String mask, String errorMessage) - { - this.mask = mask; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "413"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NoTopLevelError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getMask() - { - return mask; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotOnChannelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotOnChannelError.java deleted file mode 100644 index 8c1346012..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotOnChannelError.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 442 ERR_NOTONCHANNEL - * <channel> :You're not on that channel - * Returned by the server whenever a client tries to perform a channel effecting command for which the - * client isn't a member. - */ -public class NotOnChannelError extends GenericError -{ - private String channel; - private String errorMessage; - - public NotOnChannelError() - { - } - - public NotOnChannelError(String channel, String errorMessage) - { - this.channel = channel; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "442"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NotOnChannelError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getChannel() - { - return channel; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotRegisteredError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotRegisteredError.java deleted file mode 100644 index f443901d1..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/NotRegisteredError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 451 ERR_NOTREGISTERED - * :You have not registered - * Returned by the server to indicate that the client must be registered before the - * server will allow it to be parsed in detail. - */ -public class NotRegisteredError extends GenericError -{ - private String errorMessage; - - public NotRegisteredError() - { - } - - public NotRegisteredError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "451"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NotRegisteredError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/PasswdMismatchError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/PasswdMismatchError.java deleted file mode 100644 index b775b16c4..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/PasswdMismatchError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 464 ERR_PASSWDMISMATCH - * :Password incorrect - * Returned to indicate a failed attempt at registering a connection for which a - * password was required and was either not given or incorrect. - */ -public class PasswdMismatchError extends GenericError -{ - private String errorMessage; - - public PasswdMismatchError() - { - } - - public PasswdMismatchError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "464"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new PasswdMismatchError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/SummonDisabledError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/SummonDisabledError.java deleted file mode 100644 index 0f495fcf4..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/SummonDisabledError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 445 ERR_SUMMONDISABLED - * :SUMMON has been disabled - * Returned as a response to the SUMMON command. Must be returned by any server - * which does not implement it. - */ -public class SummonDisabledError extends GenericError -{ - private String errorMessage; - - public SummonDisabledError() - { - } - - public SummonDisabledError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "445"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new SummonDisabledError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyChannelsError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyChannelsError.java deleted file mode 100644 index a18d92b20..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyChannelsError.java +++ /dev/null @@ -1,46 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 405 ERR_TOOMANYCHANNELS - * <channel name> :You have joined too many channels - * Sent to a user when they have joined the maximum number of allowed channels and they try to join another channel. - */ -public class TooManyChannelsError extends GenericError -{ - private String channel; - private String errorMessage; - - public TooManyChannelsError() - { - } - - public TooManyChannelsError(String channel, String errorMessage) - { - this.channel = channel; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "405"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new TooManyChannelsError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getChannel() - { - return channel; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyTargetsError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyTargetsError.java deleted file mode 100644 index 594fe4e41..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/TooManyTargetsError.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 407 ERR_TOOMANYTARGETS - * <target> :Duplicate recipients. No message delivered - * Returned to a client which is attempting to send a PRIVMSG/NOTICE using the user@host destination - * format and for a user@host which has several occurrences. - */ -public class TooManyTargetsError extends GenericError -{ - private String dest; - private String errorMessage; - - public TooManyTargetsError() - { - } - - public TooManyTargetsError(String dest, String errorMessage) - { - this.dest = dest; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "407"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new TooManyTargetsError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getDest() - { - return dest; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UModeUnknownFlagError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UModeUnknownFlagError.java deleted file mode 100644 index 9f112e256..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UModeUnknownFlagError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 501 ERR_UMODEUNKNOWNFLAG - * :Unknown MODE flag - * Returned by the server to indicate that a MODE message was sent with a nickname - * parameter and that the a mode flag sent was not recognized. - */ -public class UModeUnknownFlagError extends GenericError -{ - private String errorMessage; - - public UModeUnknownFlagError() - { - } - - public UModeUnknownFlagError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "501"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new UModeUnknownFlagError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownCommandError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownCommandError.java deleted file mode 100644 index 6fd01f0ad..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownCommandError.java +++ /dev/null @@ -1,46 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 421 ERR_UNKNOWNCOMMAND - * <command> :Unknown command - * Returned to a registered client to indicate that the command sent is unknown by the server. - */ -public class UnknownCommandError extends GenericError -{ - private String command; - private String errorMessage; - - public UnknownCommandError() - { - } - - public UnknownCommandError(String command, String errorMessage) - { - this.command = command; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "421"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new UnknownCommandError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getCommand() - { - return command; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownError.java deleted file mode 100644 index 225361294..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownError.java +++ /dev/null @@ -1,69 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.commands.UnknownCommand; - - -/** - * Some unknown command, for which there is no factory. This is a - * special case command, created by IRCConnection if it can't find a - * proper command object. - */ -public class UnknownError extends UnknownCommand -{ - - private String errorStr; - private int errorCode; - - public UnknownError( String ident ) - { - errorStr = ident; - errorCode = Integer.parseInt( ident ); - } - - public int getErrorCode() - { - return errorCode; - } - - public String getError() - { - return errorStr; - } - - public static boolean isError( String ident ) - { - char c = ident.charAt(0); - return ( c == '4' || c == '5' ); - } - - public State getState() - { - return State.UNKNOWN; - } - - /** - * Never parsed. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - throw new UnsupportedOperationException("UnknownError does no parsing."); - } - - /** - * Unknown, so we don't know what the identifier is ahead of time. - */ - public String getIrcIdentifier() - { - return errorStr; - } - - public String toString() - { - return "UnknownError[" + errorStr + "]"; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownModeError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownModeError.java deleted file mode 100644 index ebd10358d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UnknownModeError.java +++ /dev/null @@ -1,45 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 472 ERR_UNKNOWNMODE - * <char> :is unknown mode char to me - */ -public class UnknownModeError extends GenericError -{ - private Character mode; - private String errorMessage; - - public UnknownModeError() - { - } - - public UnknownModeError(Character mode, String errorMessage) - { - this.mode = mode; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "472"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new UnknownModeError(getParameter(params, 1).charAt(0), getParameter(params, 2)); - } - - public Character getMode() - { - return mode; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserNotInChannelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserNotInChannelError.java deleted file mode 100644 index b1734818f..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserNotInChannelError.java +++ /dev/null @@ -1,54 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Code: 441 ERR_USERNOTINCHANNEL - * <user> <channel> :They aren't on that channel - * Returned by the server to indicate that the target user of the command is not on the given channel. - */ -public class UserNotInChannelError extends GenericError -{ - private FullNick nick; - private String channel; - private String errorMessage; - - public UserNotInChannelError() - { - } - - public UserNotInChannelError(FullNick nick, String channel, String errorMessage) - { - this.nick = nick; - this.channel = channel; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "441"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new UserNotInChannelError(new FullNick(getParameter(params, 1)), getParameter(params, 2), getParameter(params, 3)); - } - - public FullNick getNick() - { - return nick; - } - - public String getChannel() - { - return channel; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserOnChannelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserOnChannelError.java deleted file mode 100644 index 6d5b53bd2..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UserOnChannelError.java +++ /dev/null @@ -1,54 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Code: 443 ERR_USERONCHANNEL - * <user> <channel> :is already on channel - * Returned when a client tries to invite a user to a channel they are already on. - */ -public class UserOnChannelError extends GenericError -{ - private FullNick nick; - private String channel; - private String errorMessage; - - public UserOnChannelError() - { - } - - public UserOnChannelError(FullNick nick, String channel, String errorMessage) - { - this.nick = nick; - this.channel = channel; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "443"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new UserOnChannelError(new FullNick(getParameter(params, 1)), getParameter(params, 2), getParameter(params, 3)); - } - - public FullNick getNick() - { - return nick; - } - - public String getChannel() - { - return channel; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDisabledError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDisabledError.java deleted file mode 100644 index b09c0f929..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDisabledError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 446 ERR_USERSDISABLED - * :USERS has been disabled - * Returned as a response to the USERS command. Must be returned by any server which - * does not implement it. - */ -public class UsersDisabledError extends GenericError -{ - private String errorMessage; - - public UsersDisabledError() - { - } - - public UsersDisabledError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "446"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new UsersDisabledError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDontMatchError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDontMatchError.java deleted file mode 100644 index e8fe565e4..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/UsersDontMatchError.java +++ /dev/null @@ -1,39 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 502 ERR_USERSDONTMATCH - * :Cant change mode for other users - * Error sent to any user trying to view or change the user mode for a user other than themselves. - */ -public class UsersDontMatchError extends GenericError -{ - private String errorMessage; - - public UsersDontMatchError() - { - } - - public UsersDontMatchError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "502"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new UsersDontMatchError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WasNoSuchNickError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WasNoSuchNickError.java deleted file mode 100644 index 82c0545d7..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WasNoSuchNickError.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.FullNick; - -/** - * Code: 406 ERR_WASNOSUCHNICK - * <nickname> :There was no such nickname - * Returned by WHOWAS to indicate there is no history information for that nickname. - */ -public class WasNoSuchNickError extends GenericError -{ - private FullNick nick; - private String errorMessage; - - public WasNoSuchNickError() - { - } - - public WasNoSuchNickError(FullNick nick, String errorMessage) - { - this.nick = nick; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "406"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new WasNoSuchNickError(new FullNick(getParameter(params, 1)), getParameter(params, 2)); - } - - public FullNick getNick() - { - return nick; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WildTopLevelError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WildTopLevelError.java deleted file mode 100644 index 2fb641f24..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/WildTopLevelError.java +++ /dev/null @@ -1,48 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 414 ERR_WILDTOPLEVEL - * <mask> :Wildcard in toplevel domain - * 412 - 414 are returned by PRIVMSG to indicate that the message wasn't delivered for some reason. - * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that are returned when an invalid use of - * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. - */ -public class WildTopLevelError extends GenericError -{ - private String mask; - private String errorMessage; - - public WildTopLevelError() - { - } - - public WildTopLevelError(String mask, String errorMessage) - { - this.mask = mask; - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "414"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new WildTopLevelError(getParameter(params, 1), getParameter(params, 2)); - } - - public String getMask() - { - return mask; - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/YoureBannedCreepError.java b/EssentialsUpdate/src/f00f/net/irc/martyr/errors/YoureBannedCreepError.java deleted file mode 100644 index 1cea503dc..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/errors/YoureBannedCreepError.java +++ /dev/null @@ -1,40 +0,0 @@ -package f00f.net.irc.martyr.errors; - -import f00f.net.irc.martyr.InCommand; - -/** - * Code: 465 ERR_YOUREBANNEDCREEP - * :You are banned from this server - * Returned after an attempt to connect and register yourself with a server which has been setup to - * explicitly deny connections to you. - */ -public class YoureBannedCreepError extends GenericError -{ - private String errorMessage; - - public YoureBannedCreepError() - { - } - - public YoureBannedCreepError(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getIrcIdentifier() - { - return "465"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new YoureBannedCreepError(getParameter(params, 1)); - } - - public String getErrorMessage() - { - return errorMessage; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/GenericMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/GenericMode.java deleted file mode 100644 index e1dad6045..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/GenericMode.java +++ /dev/null @@ -1,77 +0,0 @@ -package f00f.net.irc.martyr.modes; - -import f00f.net.irc.martyr.Mode; - -/** - * GenericNode uses the character to specify the hash code. Thus, two - * mode types are the same, in a hash table, even if they have - * different parameters or positive/negative values. - */ -public abstract class GenericMode implements Mode -{ - private String str; - private Mode.Sign sign = Mode.Sign.NOSIGN; - - public void setParam( String str ) - { - this.str = str; - } - - public String getParam() - { - return str; - } - - public void setSign( Mode.Sign sign ) - { - this.sign = sign; - } - - public Mode.Sign getSign() - { - return sign; - } - - public String toString() - { - String pString = " "; - if( sign != Mode.Sign.NOSIGN ) - pString += ( sign == Mode.Sign.POSITIVE ? "+" : "-" ); - String className = this.getClass().getName(); - className = className.substring( className.indexOf('$')+1 ); - - String result = className + pString + getChar(); - if( requiresParam() ) - { - result += " " + getParam(); - } - - return result; - } - - public boolean equals( Object o ) - { - if( o instanceof Mode ) - { - Mode oMode = (Mode)o; - - if( oMode.getParam() == null || this.getParam() == null ) - return oMode.getChar() == this.getChar(); - - if( oMode.getParam() == null && this.getParam() != null ) - return false; - if( oMode.getParam() == null && this.getParam() == null ) - return oMode.getChar() == this.getChar(); - - return oMode.getChar() == this.getChar() && - oMode.getParam().equals(this.getParam()); - } - return false; - } - - public int hashCode() - { - return (int)getChar(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/README b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/README deleted file mode 100644 index 8d2e25c18..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/README +++ /dev/null @@ -1,8 +0,0 @@ -This directory contains modes. Unlike commands, errors, and replies, -these modes do NOT contain any information about the mode other than -what it is. The Mode objects know if the mode takes a parameter, what -character represents the mode, and contain a method to create a new -instance of itself. - -You can get and set parameters using the Mode related commands. - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/AnonChannelMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/AnonChannelMode.java deleted file mode 100644 index 9fd215416..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/AnonChannelMode.java +++ /dev/null @@ -1,44 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

The channel flag 'a' defines an anonymous channel. This means that - * when a message sent to the channel is sent by the server to users, - * and the origin is a user, then it MUST be masked. To mask the - * message, the origin is changed to "anonymous!anonymous@anonymous." - * (e.g., a user with the nickname "anonymous", the username "anonymous" - * and from a host called "anonymous."). Because of this, servers MUST - * forbid users from using the nickname "anonymous". Servers MUST also - * NOT send QUIT messages for users leaving such channels to the other - * channel members but generate a PART message instead.

- * - *

On channels with the character '&' as prefix, this flag MAY be - * toggled by channel operators, but on channels with the character '!' - * as prefix, this flag can be set (but SHALL NOT be unset) by the - * "channel creator" only. This flag MUST NOT be made available on - * other types of channels.

- * - *

Replies to the WHOIS, WHO and NAMES commands MUST NOT reveal the - * presence of other users on channels for which the anonymous flag is - * set.

- * (From RFC2811) - */ -public class AnonChannelMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return false; - } - - public char getChar() - { - return 'a'; - } - - public Mode newInstance() - { - return new AnonChannelMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/BanMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/BanMode.java deleted file mode 100644 index d169370cb..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/BanMode.java +++ /dev/null @@ -1,38 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Channel Ban and Exception - When a user requests to join a - * channel, his local server checks if the user's address matches - * any of the ban masks set for the channel. If a match is found, - * the user request is denied unless the address also matches an - * exception mask set for the channel.

- * - *

Servers MUST NOT allow a channel member who is banned from the - * channel to speak on the channel, unless this member is a channel - * operator or has voice privilege. (See Section 4.1.3 (Voice - * Privilege)).

- * - *

A user who is banned from a channel and who carries an invitation - * sent by a channel operator is allowed to join the channel.

- * (From RFC2811) - */ -public class BanMode extends GenericChannelMask -{ - public boolean requiresParam() - { - return true; - } - - public char getChar() - { - return 'b'; - } - - public Mode newInstance() - { - return new BanMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ExceptionMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ExceptionMode.java deleted file mode 100644 index 63f3d03f8..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ExceptionMode.java +++ /dev/null @@ -1,38 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Channel Ban and Exception - When a user requests to join a - * channel, his local server checks if the user's address matches - * any of the ban masks set for the channel. If a match is found, - * the user request is denied unless the address also matches an - * exception mask set for the channel.

- * - *

Servers MUST NOT allow a channel member who is banned from the - * channel to speak on the channel, unless this member is a channel - * operator or has voice privilege. (See Section 4.1.3 (Voice - * Privilege)).

- * - *

A user who is banned from a channel and who carries an invitation - * sent by a channel operator is allowed to join the channel.

- * (From RFC2811) -*/ -public class ExceptionMode extends GenericChannelMask -{ - public boolean requiresParam() - { - return true; - } - - public char getChar() - { - return 'e'; - } - - public Mode newInstance() - { - return new ExceptionMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMask.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMask.java deleted file mode 100644 index 13e1fc3de..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMask.java +++ /dev/null @@ -1,16 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - - -/** - * 'Masks' and other modes that can have multiple copies in a channel - * at once should subclass this. - */ -public abstract class GenericChannelMask extends GenericChannelMode -{ - public boolean onePerChannel() - { - return false; - } -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMode.java deleted file mode 100644 index d65f850b8..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/GenericChannelMode.java +++ /dev/null @@ -1,23 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.modes.GenericMode; - -/** - * A generic channel mode will be recorded in the channel, and there - * will be one per channel. Modes that can have multiple copies in - * the channel (masks) should subclass GenericChannelMask. - */ -public abstract class GenericChannelMode extends GenericMode -{ - public boolean recordInChannel() - { - return true; - } - - public boolean onePerChannel() - { - return true; - } -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteMaskMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteMaskMode.java deleted file mode 100644 index c9faa27fc..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteMaskMode.java +++ /dev/null @@ -1,30 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Channel Invitation - For channels which have the invite-only - * flag set (See Section 4.2.2 (Invite Only Flag)), users whose - * address matches an invitation mask set for the channel are - * allowed to join the channel without any - * invitation.

- * (From RFC2811) - */ -public class InviteMaskMode extends GenericChannelMask -{ - public boolean requiresParam() - { - return true; - } - - public char getChar() - { - return 'I'; - } - - public Mode newInstance() - { - return new InviteMaskMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteOnlyMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteOnlyMode.java deleted file mode 100644 index 45da646c9..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/InviteOnlyMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Invite Only Flag - When the channel flag 'i' is set, new - * members are only accepted if their mask matches Invite-list (See - * section 4.3.2) or they have been invited by a channel operator. - * This flag also restricts the usage of the INVITE command (See - * "IRC Client Protocol" [IRC-CLIENT]) to channel operators.

- * (From RFC2811) - * - * @see InviteMaskMode - */ -public class InviteOnlyMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return false; - } - - public char getChar() - { - return 'i'; - } - - public Mode newInstance() - { - return new InviteOnlyMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/KeyMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/KeyMode.java deleted file mode 100644 index 9f29da431..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/KeyMode.java +++ /dev/null @@ -1,31 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Channel Key - When a channel key is set (by using the mode - * 'k'), servers MUST reject their local users request to join the - * channel unless this key is given.

- * - *

The channel key MUST only be made visible to the channel members in - * the reply sent by the server to a MODE query.

- * (From RFC2811) - */ -public class KeyMode extends GenericChannelMask -{ - public boolean requiresParam() - { - return true; - } - - public char getChar() - { - return 'k'; - } - - public Mode newInstance() - { - return new KeyMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/LimitMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/LimitMode.java deleted file mode 100644 index 028739705..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/LimitMode.java +++ /dev/null @@ -1,31 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

User Limit - A user limit may be set on channels by using the - * channel flag 'l'. When the limit is reached, servers MUST - * forbid their local users to join the channel.

- * - *

The value of the limit MUST only be made available to the channel - * members in the reply sent by the server to a MODE query.

- * (From RFC2811) -*/ -public class LimitMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return true; - } - - public char getChar() - { - return 'l'; - } - - public Mode newInstance() - { - return new LimitMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ModeratedMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ModeratedMode.java deleted file mode 100644 index d0938a565..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/ModeratedMode.java +++ /dev/null @@ -1,31 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Moderated Channel Flag - The channel flag 'm' is used to - * control who may speak on a channel. When it is set, only - * channel operators, and members who have been given the voice - * privilege may send messages to the channel.

- * - *

This flag only affects users.

- * (From RFC2811) - */ -public class ModeratedMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return false; - } - - public char getChar() - { - return 'm'; - } - - public Mode newInstance() - { - return new ModeratedMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/NoExtMsgMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/NoExtMsgMode.java deleted file mode 100644 index 029baf760..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/NoExtMsgMode.java +++ /dev/null @@ -1,30 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

No Messages To Channel From Clients On The Outside - When the - * channel flag 'n' is set, only channel members MAY send messages - * to the channel.

- * - *

This flag only affects users.

- * (From RFC2811) - */ -public class NoExtMsgMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return false; - } - - public char getChar() - { - return 'n'; - } - - public Mode newInstance() - { - return new NoExtMsgMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/OperMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/OperMode.java deleted file mode 100644 index e8f45f0be..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/OperMode.java +++ /dev/null @@ -1,31 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Channel Operator Status - The mode 'o' is used to toggle the - * operator status of a channel member.

(From RFC2811) - * - *

Note that OperMode is recorded in the channel, but checking the op - * status of a member will give you a true list of who is and isn't an - * operator. This is because we don't know the entire list of modes - * when entering a channel.

- */ -public class OperMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return true; - } - - public char getChar() - { - return 'o'; - } - - public Mode newInstance() - { - return new OperMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/PrivateMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/PrivateMode.java deleted file mode 100644 index 580b957e6..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/PrivateMode.java +++ /dev/null @@ -1,50 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Private and Secret Channels - The channel flag 'p' is used to - * mark a channel "private" and the channel flag 's' to mark a - * channel "secret". Both properties are similar and conceal the - * existence of the channel from other users.

- * - *

This means that there is no way of getting this channel's name from - * the server without being a member. In other words, these channels - * MUST be omitted from replies to queries like the WHOIS - * command.

- * - *

When a channel is "secret", in addition to the restriction above, the - * server will act as if the channel does not exist for queries like the - * TOPIC, LIST, NAMES commands. Note that there is one exception to - * this rule: servers will correctly reply to the MODE command. - * Finally, secret channels are not accounted for in the reply to the - * LUSERS command (See "Internet Relay Chat: Client Protocol" [IRC- - * CLIENT]) when the <mask> parameter is specified.

- * - *

The channel flags 'p' and 's' MUST NOT both be set at the same time. - * If a MODE message originating from a server sets the flag 'p' and the - * flag 's' is already set for the channel, the change is silently - * ignored. This should only happen during a split healing phase - * (mentioned in the "IRC Server Protocol" document - * [IRC-SERVER]).

- * - * (From RFC2811) - */ -public class PrivateMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return false; - } - - public char getChar() - { - return 'p'; - } - - public Mode newInstance() - { - return new PrivateMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/SecretMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/SecretMode.java deleted file mode 100644 index 33bb13733..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/SecretMode.java +++ /dev/null @@ -1,50 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Private and Secret Channels - The channel flag 'p' is used to - * mark a channel "private" and the channel flag 's' to mark a - * channel "secret". Both properties are similar and conceal the - * existence of the channel from other users.

- * - *

This means that there is no way of getting this channel's name from - * the server without being a member. In other words, these channels - * MUST be omitted from replies to queries like the WHOIS - * command.

- * - *

When a channel is "secret", in addition to the restriction above, the - * server will act as if the channel does not exist for queries like the - * TOPIC, LIST, NAMES commands. Note that there is one exception to - * this rule: servers will correctly reply to the MODE command. - * Finally, secret channels are not accounted for in the reply to the - * LUSERS command (See "Internet Relay Chat: Client Protocol" [IRC- - * CLIENT]) when the <mask> parameter is specified.

- * - *

The channel flags 'p' and 's' MUST NOT both be set at the same time. - * If a MODE message originating from a server sets the flag 'p' and the - * flag 's' is already set for the channel, the change is silently - * ignored. This should only happen during a split healing phase - * (mentioned in the "IRC Server Protocol" document - * [IRC-SERVER]).

- * - * (From RFC2811) - */ -public class SecretMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return false; - } - - public char getChar() - { - return 's'; - } - - public Mode newInstance() - { - return new SecretMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/TopicLockMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/TopicLockMode.java deleted file mode 100644 index c6f9b8a81..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/TopicLockMode.java +++ /dev/null @@ -1,27 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Topic - The channel flag 't' is used to restrict the usage of the TOPIC - * command to channel operators.

- * (From RFC2811) - */ -public class TopicLockMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return false; - } - - public char getChar() - { - return 't'; - } - - public Mode newInstance() - { - return new TopicLockMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/VoiceMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/VoiceMode.java deleted file mode 100644 index 8d5faeac3..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/channel/VoiceMode.java +++ /dev/null @@ -1,34 +0,0 @@ -package f00f.net.irc.martyr.modes.channel; - -import f00f.net.irc.martyr.Mode; - -/** - *

Voice Privilege - The mode 'v' is used to give and take voice - * privilege to/from a channel member. Users with this privilege - * can talk on moderated channels. (See section 4.2.3 (Moderated - * Channel Flag).

- * (From RFC2811) - */ -public class VoiceMode extends GenericChannelMode -{ - public boolean requiresParam() - { - return true; - } - - public char getChar() - { - return 'v'; - } - - public boolean recordInChannel() - { - return false; - } - - public Mode newInstance() - { - return new VoiceMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/GenericUserMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/GenericUserMode.java deleted file mode 100644 index 7a3767d2d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/GenericUserMode.java +++ /dev/null @@ -1,24 +0,0 @@ -package f00f.net.irc.martyr.modes.user; - -import f00f.net.irc.martyr.modes.GenericMode; - -/** - * - */ -public abstract class GenericUserMode extends GenericMode -{ - public boolean recordInChannel() - { - return false; - } - - /** - * Well, this is kind of irrelevent isn't it? - */ - public boolean onePerChannel() - { - return false; - } -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/InvisibleMode.java b/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/InvisibleMode.java deleted file mode 100644 index f86da15a5..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/modes/user/InvisibleMode.java +++ /dev/null @@ -1,22 +0,0 @@ -package f00f.net.irc.martyr.modes.user; - -import f00f.net.irc.martyr.Mode; - -public class InvisibleMode extends GenericUserMode -{ - public char getChar() - { - return 'i'; - } - - public boolean requiresParam() - { - return false; - } - - public Mode newInstance() - { - return new InvisibleMode(); - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AbstractWhoisReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AbstractWhoisReply.java deleted file mode 100644 index d52e59dcf..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AbstractWhoisReply.java +++ /dev/null @@ -1,58 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.util.ParameterIterator; - -public abstract class AbstractWhoisReply extends GenericReply -{ - //static Logger log = Logger.getLogger(AbstractWhoisReply.class); - - private String target = null; - - /** - * Factory constructor. - * */ - public AbstractWhoisReply() - { - } - - public AbstractWhoisReply( String params ) - { - ParameterIterator pi = getParams( params ); - parseParams( pi ); - } - - public abstract String getIrcIdentifier(); - - /** - * Parse the parameters, but the target param has already been - * stripped off. - * - * @param pi Parameter iterator that will parse the parameters - * */ - protected abstract void parseParams( ParameterIterator pi ); - - /** - * @return the target of the whois - * */ - public String getTarget() - { - return target; - } - - /** - * @param params the params string passed to "parse". - * @return a parameter iterator, with the whois target already - * stripped off. - * */ - protected ParameterIterator getParams( String params ) - { - ParameterIterator pi = new ParameterIterator(params); - pi.next(); // throw away our own nick - this.target = (String)pi.next(); - //log.debug("AbstractWhoisReply: Whois target: " + target); - - return pi; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AwayReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AwayReply.java deleted file mode 100644 index a7105546e..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/AwayReply.java +++ /dev/null @@ -1,49 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -/** - * Signals an automated AWAY message received as a response to a PRIVMSG that was sent out. - * - * @author Daniel Henninger - */ -public class AwayReply extends GenericReply -{ - - private String nick; - private String message; - - /** - * Factory constructor. - */ - public AwayReply() - { - } - - public AwayReply(String nick, String message) - { - this.nick = nick; - this.message = message; - } - - public String getIrcIdentifier() - { - return "301"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new AwayReply(getParameter(params, 1), getParameter(params, 2)); - } - - public String getNick() - { - return nick; - } - - public String getMessage() - { - return message; - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ChannelCreationReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ChannelCreationReply.java deleted file mode 100644 index 2dd89e1cd..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ChannelCreationReply.java +++ /dev/null @@ -1,78 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import java.util.Date; -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; - -/** - * ChannelCreationReply sets the creation time of the channel. It is sent - * automatically on a MODE discovery request. - */ -public class ChannelCreationReply extends GenericReply -{ - private String channelName; - private Date date; - - /** For use as a factory. */ - public ChannelCreationReply() - { - } - - public ChannelCreationReply( String channelName, Date date ) - { - this.channelName = channelName; - this.date = date; - } - - public String getIrcIdentifier() - { - return "329"; - } - - /** - * This is a factory that passes the command off to a - * ChannelModeCommand. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - StringTokenizer tokens = new StringTokenizer( params ); - - // Our nick. We don't need that, I think. - tokens.nextToken(); - - // The channel. - String chan = tokens.nextToken(); - - // The date. - Date date; - try - { - date = new Date( Long.parseLong( tokens.nextToken() ) * 1000 ); - } - catch( NumberFormatException nfe ) - { - // riiiight... - date = new Date(0); - } - - return new ChannelCreationReply( chan, date ); - } - - /** - * This should, theoretically, never be called, because this command is - * only ever used as a factory. - */ - public boolean updateClientState( ClientState state ) - { - Channel channel = state.getChannel( channelName ); - channel.setCreationDate( date ); - return true; - } -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericReply.java deleted file mode 100644 index eabdf2658..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericReply.java +++ /dev/null @@ -1,16 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.commands.AbstractInCommand; - -/** - * Defines what a reply is. A reply is really the same as an error, - * it just doesn't signify an error. - */ -public abstract class GenericReply extends AbstractInCommand -{ - - -} - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericStringReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericStringReply.java deleted file mode 100644 index 38d609ac6..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/GenericStringReply.java +++ /dev/null @@ -1,23 +0,0 @@ -package f00f.net.irc.martyr.replies; - -public abstract class GenericStringReply extends GenericReply -{ - - private String string; - - public GenericStringReply() - { - } - - public GenericStringReply( String string ) - { - this.string = string; - } - - public String getString() - { - return string; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserClientReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserClientReply.java deleted file mode 100644 index c108fe919..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserClientReply.java +++ /dev/null @@ -1,28 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -public class LUserClientReply extends GenericStringReply -{ - - public LUserClientReply() - { - } - - public LUserClientReply( String string ) - { - super( string ); - } - - public String getIrcIdentifier() - { - return "251"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new LUserClientReply( getParameter( params, 1 ) ); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserMeReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserMeReply.java deleted file mode 100644 index 9083f0a73..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserMeReply.java +++ /dev/null @@ -1,28 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -public class LUserMeReply extends GenericStringReply -{ - - public LUserMeReply() - { - } - - public LUserMeReply( String string ) - { - super( string ); - } - - public String getIrcIdentifier() - { - return "255"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new LUserMeReply( getParameter( params, 1 ) ); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserOpReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserOpReply.java deleted file mode 100644 index b05efedc1..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/LUserOpReply.java +++ /dev/null @@ -1,36 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -public class LUserOpReply extends GenericStringReply -{ - - private int numOps; - - public LUserOpReply() - { - } - - public LUserOpReply( int ops, String string ) - { - super( string ); - this.numOps = ops; - } - - public String getIrcIdentifier() - { - return "252"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new LUserOpReply( getIntParameter( params, 1, -1 ), getParameter( params, 2 ) ); - } - - public int getNumOps() - { - return numOps; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListEndReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListEndReply.java deleted file mode 100644 index 6a0b1ca7f..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListEndReply.java +++ /dev/null @@ -1,31 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -/** - * Signals the end of a LIST response. - * - * @author Daniel Henninger - */ -public class ListEndReply extends GenericReply -{ - - /** - * Factory constructor. - */ - public ListEndReply() - { - } - - public String getIrcIdentifier() - { - return "323"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new ListEndReply(); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListReply.java deleted file mode 100644 index a814c5a43..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListReply.java +++ /dev/null @@ -1,63 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -/** - * Signals an entry of a LIST response. - * - * @author Daniel Henninger - */ -public class ListReply extends GenericReply -{ - - private String requestor; - private String channel; - private Integer memberCount; - private String topic; - - /** - * Factory constructor. - */ - public ListReply() - { - } - - public ListReply(String requestor, String channel, Integer memberCount, String topic) - { - this.requestor = requestor; - this.channel = channel; - this.memberCount = memberCount; - this.topic = topic; - } - - public String getIrcIdentifier() - { - return "322"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new ListReply(getParameter(params, 0), getParameter(params, 1), Integer.parseInt(getParameter(params, 2)), getParameter(params, 3)); - } - - public String getChannel() - { - return channel; - } - - public Integer getMemberCount() - { - return memberCount; - } - - public String getTopic() - { - return topic; - } - - public String getRequestor() - { - return requestor; - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListStartReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListStartReply.java deleted file mode 100644 index 0f00d6c3f..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ListStartReply.java +++ /dev/null @@ -1,31 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -/** - * Signals the beginning of a LIST response. - * - * @author Daniel Henninger - */ -public class ListStartReply extends GenericReply -{ - - /** - * Factory constructor. - */ - public ListStartReply() - { - } - - public String getIrcIdentifier() - { - return "321"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new ListStartReply(); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ModeReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ModeReply.java deleted file mode 100644 index d355e45e3..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/ModeReply.java +++ /dev/null @@ -1,54 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.commands.ChannelModeCommand; - -/** - * ModeReply is really a factory that passes the ModeReply off to a - * ChannelModeCommand. - */ -public class ModeReply extends GenericReply -{ - - /** For use as a factory. */ - public ModeReply() - { - } - - public String getIrcIdentifier() - { - return "324"; - } - - /** - * This is a factory that passes the command off to a - * ChannelModeCommand. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - StringTokenizer tokens = new StringTokenizer( params ); - - // Our nick. We don't need that, I think. - tokens.nextToken(); - - String chan = tokens.nextToken(); - - return new ChannelModeCommand( prefix, chan, tokens ); - } - - /** - * This should, theoretically, never be called, because this command is - * only ever used as a factory. - */ - public boolean updateClientState( ClientState state ) - { - throw new IllegalStateException("This shouldn't be called!" ); - } -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesEndReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesEndReply.java deleted file mode 100644 index a0605b5bd..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesEndReply.java +++ /dev/null @@ -1,47 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -public class NamesEndReply extends GenericReply -{ - - private String channel; - private String comment; - - /** For use as a factory. */ - public NamesEndReply() - { - this( null, null ); - } - - public NamesEndReply( String channel, String comment ) - { - this.channel = channel; - this.comment = comment; - } - - public String getIrcIdentifier() - { - return "366"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NamesEndReply( getParameter( params, 1 ), getParameter( params, 2 ) ); - } - - public String getChannel() - { - return channel; - } - - public String getComment() - { - return comment; - } - -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesReply.java deleted file mode 100644 index acd5045f6..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NamesReply.java +++ /dev/null @@ -1,89 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import java.util.List; -import java.util.Arrays; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; -import java.util.logging.Logger; - -public class NamesReply extends GenericReply -{ - static Logger log = Logger.getLogger(NamesReply.class.getName()); - - private List names; - private String channel; - - /** For use as a factory. */ - public NamesReply() - { - } - - public NamesReply( String channel, List names ) - { - this.names = names; - this.channel = channel; - } - - public String getIrcIdentifier() - { - return "353"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NamesReply( getParameter( params, 2 ), Arrays.asList(getParameter( params, 3 ).split(" ")) ); - } - - /** - * Adds the list of names to the client state. - */ - public boolean updateClientState( ClientState state ) - { - boolean stateChanged = false; - - // 1) Get the Channel - Channel channelObj = state.getChannel( channel ); - - if( channel == null ) - { - log.severe("NamesReply: Channel is null"); - return false; - } - - if( channelObj == null ) - { - log.severe("NamesReply: No channel object for channel: " + channel); - return false; - } - - - // 2) Parse out names - for (String nick : names) { - // 3) Check that the user is not already in the list - if( !channelObj.isMemberInChannel( nick ) ) - { - channelObj.addMember( nick, this ); - stateChanged = true; - } - } - - return stateChanged; - } - - public List getNames() - { - return names; - } - - public String getChannel() - { - return channel; - } - -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NowAwayReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NowAwayReply.java deleted file mode 100644 index 012431112..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/NowAwayReply.java +++ /dev/null @@ -1,43 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -/** - * Signals that you were successfully marked un-away. - * - * @author Daniel Henninger - */ -public class NowAwayReply extends GenericReply -{ - - /* Should always be You have been marked as being away */ - private String message; - - /** - * Factory constructor. - */ - public NowAwayReply() - { - } - - public NowAwayReply(String message) - { - this.message = message; - } - - public String getIrcIdentifier() - { - return "306"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new NowAwayReply(getParameter(params, 0)); - } - - public String getMessage() - { - return message; - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/TopicInfoReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/TopicInfoReply.java deleted file mode 100644 index 311e17dc8..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/TopicInfoReply.java +++ /dev/null @@ -1,80 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import java.util.Date; -import java.util.StringTokenizer; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.clientstate.ClientState; - -/** - * Contains info about the topic, who set it and when. - */ -public class TopicInfoReply extends GenericReply -{ - private String channelName; - private Date date; - private String author; - - /** For use as a factory. */ - public TopicInfoReply() - { - } - - public TopicInfoReply( String channelName, Date date, String author ) - { - this.channelName = channelName; - this.date = date; - this.author = author; - } - - public String getIrcIdentifier() - { - return "333"; - } - - public String getChannel() - { - return this.channelName; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - StringTokenizer tokens = new StringTokenizer( params ); - - // Our nick. We don't need that, I think. - tokens.nextToken(); - - // The channel. - String chan = tokens.nextToken(); - - // The author - String author = tokens.nextToken(); - - // The date. - Date date; - try - { - date = new Date( Long.parseLong( tokens.nextToken() ) * 1000 ); - } - catch( NumberFormatException nfe ) - { - // riiiight... - date = new Date(0); - } - - return new TopicInfoReply( chan, date, author ); - } - - public boolean updateClientState( ClientState state ) - { - Channel channel = state.getChannel( channelName ); - channel.setTopicDate( date ); - channel.setTopicAuthor( author ); - return true; - } -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnAwayReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnAwayReply.java deleted file mode 100644 index f4652f0ce..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnAwayReply.java +++ /dev/null @@ -1,43 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; - -/** - * Signals that you were successfully marked un-away. - * - * @author Daniel Henninger - */ -public class UnAwayReply extends GenericReply -{ - - /* Should always be You are no longer marked as being away */ - private String message; - - /** - * Factory constructor. - */ - public UnAwayReply() - { - } - - public UnAwayReply(String message) - { - this.message = message; - } - - public String getIrcIdentifier() - { - return "305"; - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new UnAwayReply(getParameter(params, 0)); - } - - public String getMessage() - { - return message; - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnknownReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnknownReply.java deleted file mode 100644 index f4ebc14d6..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/UnknownReply.java +++ /dev/null @@ -1,66 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.commands.UnknownCommand; - - -/** - * A container for unknown replies. - */ -public class UnknownReply extends UnknownCommand -{ - private String replyStr; - private int replyCode; - - public UnknownReply( String ident ) - { - replyStr = ident; - replyCode = Integer.parseInt( ident ); - } - - public int getReplyCode() - { - return replyCode; - } - - public String getReply() - { - return replyStr; - } - - public static boolean isReply( String ident ) - { - char c = ident.charAt(0); - return ( c == '0' || c == '2' || c == '3' ); - } - - public State getState() - { - return State.UNKNOWN; - } - - /** - * Never parsed. - */ - public InCommand parse( String prefix, String identifier, String params ) - { - throw new UnsupportedOperationException("UnknownReply does no parsing."); - } - - /** - * Unknown, so we don't know what the identifier is ahead of time. - */ - public String getIrcIdentifier() - { - return replyStr; - } - - public String toString() - { - return "UnknownReply[" + replyStr + "]"; - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisChannelsReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisChannelsReply.java deleted file mode 100644 index 0eee5eb2f..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisChannelsReply.java +++ /dev/null @@ -1,70 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.ParameterIterator; -import java.util.HashSet; -import java.util.Set; -import java.util.StringTokenizer; - -//import org.apache.log4j.Logger; - -public class WhoisChannelsReply extends AbstractWhoisReply -{ - //static Logger log = Logger.getLogger(WhoisChannelsReply.class); - - private String channels; - - /** - * Factory constructor. - * */ - public WhoisChannelsReply() - { - } - - public WhoisChannelsReply( String params ) - { - super( params ); - } - - public String getIrcIdentifier() - { - return "319"; - } - - /** - * @return a space-delimited list of channels - * */ - public String getChannels() - { - return channels; - } - - /** - * @return a set of Strings of channels - * */ - public Set getChannelSet() - { - StringTokenizer tokens = new StringTokenizer( channels ); - Set set = new HashSet(); - while( tokens.hasMoreTokens() ) - { - set.add( tokens.nextToken() ); - } - - return set; - } - - protected void parseParams( ParameterIterator pi ) - { - channels = pi.last(); // Channels - - //log.debug("WhoisChannelsReply: channels: " + channels); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new WhoisChannelsReply( params ); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisEndReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisEndReply.java deleted file mode 100644 index ce9def847..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisEndReply.java +++ /dev/null @@ -1,37 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.ParameterIterator; - -public class WhoisEndReply extends AbstractWhoisReply -{ - /** - * Factory constructor. - * */ - public WhoisEndReply() - { - } - - public WhoisEndReply( String params ) - { - super( params ); - } - - public String getIrcIdentifier() - { - return "318"; - } - - - protected void parseParams( ParameterIterator pi ) - { - // nothing to do here - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new WhoisEndReply( params ); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisIdleReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisIdleReply.java deleted file mode 100644 index aba98205d..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisIdleReply.java +++ /dev/null @@ -1,68 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.ParameterIterator; -import java.util.Date; - -//import org.apache.log4j.Logger; - -public class WhoisIdleReply extends AbstractWhoisReply -{ - //static Logger log = Logger.getLogger(WhoisIdleReply.class); - - private int idleTime; - private Date loginTime; - - /** - * Factory constructor. - * */ - public WhoisIdleReply() - { - } - - public WhoisIdleReply( String params ) - { - super( params ); - } - - public String getIrcIdentifier() - { - return "317"; - } - - /** - * @return seconds idle - * */ - public int getIdleTime() - { - return idleTime; - } - - /** - * @return login time, if provided, null otherwise - * */ - public Date getLoginTime() - { - return loginTime; - } - - protected void parseParams( ParameterIterator pi ) - { - String idleTimeStr = (String)pi.next(); // Idle name - idleTime = Integer.parseInt( idleTimeStr ); - if( pi.hasNext() && ! pi.nextIsLast() ) - { - String loginTimeStr = (String)pi.next(); // Idle description - loginTime = new Date( Long.parseLong( loginTimeStr ) * 1000 ); - } - //log.debug("WhoisIdleReply: idle: " + idleTime); - //log.debug("WhoisIdleReply: login: " + loginTime); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new WhoisIdleReply( params ); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisServerReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisServerReply.java deleted file mode 100644 index d1f4d6344..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisServerReply.java +++ /dev/null @@ -1,61 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.ParameterIterator; -//import org.apache.log4j.Logger; - -public class WhoisServerReply extends AbstractWhoisReply -{ - //static Logger log = Logger.getLogger(WhoisServerReply.class); - - private String serverName; - private String serverDesc; - - /** - * Factory constructor. - * */ - public WhoisServerReply() - { - } - - public WhoisServerReply( String params ) - { - super( params ); - } - - public String getIrcIdentifier() - { - return "312"; - } - - /** - * @return the DNS name of the server - * */ - public String getServerName() - { - return serverName; - } - - /** - * @return the free-form description of the server - * */ - public String getServerDescription() - { - return serverDesc; - } - - protected void parseParams( ParameterIterator pi ) - { - serverName = (String)pi.next(); // Server name - serverDesc = (String)pi.next(); // Server description - //log.debug("WhoisServerReply: server name: " + serverName); - //log.debug("WhoisServerReply: server desc: " + serverDesc); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new WhoisServerReply( params ); - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisUserReply.java b/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisUserReply.java deleted file mode 100644 index a896c65e6..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/replies/WhoisUserReply.java +++ /dev/null @@ -1,54 +0,0 @@ -package f00f.net.irc.martyr.replies; - -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.util.ParameterIterator; - -public class WhoisUserReply extends AbstractWhoisReply -{ - - private String host; - private String name; - - /** - * Factory constructor. - * */ - public WhoisUserReply() - { - } - - public WhoisUserReply( String params ) - { - super( params ); - } - - public String getIrcIdentifier() - { - return "311"; - } - - protected void parseParams( ParameterIterator pi ) - { - pi.next(); // throw away the nick - host = (String)pi.next(); // hostmask - //log.debug("WhoisUserReply: host: " + host); - name = pi.last(); // the "Name" - //log.debug("WhoisUserReply: name: " + name); - } - - public InCommand parse( String prefix, String identifier, String params ) - { - return new WhoisUserReply( params ); - } - - public String getHost() - { - return host; - } - - public String getName() - { - return name; - } - -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoJoin.java b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoJoin.java deleted file mode 100644 index 786552a7b..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoJoin.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Original version: Ben Damm - * Changes by: Morgan Christiansson - * - Spotted bugs - * - Added timer - * - Responds to Invites - * - Re-tries a join with a bad key - * - * Note: Requires Java 1.4 - */ -package f00f.net.irc.martyr.services; - -import f00f.net.irc.martyr.GenericAutoService; -import f00f.net.irc.martyr.IRCConnection; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.TimerTaskCommand; -import f00f.net.irc.martyr.clientstate.Channel; -import f00f.net.irc.martyr.commands.InviteCommand; -import f00f.net.irc.martyr.commands.JoinCommand; -import f00f.net.irc.martyr.commands.KickCommand; -import f00f.net.irc.martyr.errors.GenericJoinError; - -/** - *

AutoJoin joins a group if the IRCConnection is ready. It will wait until - * it is ready if it is not (by waiting for the REGISTERED state change).

- * - *

AutoJoin maintains a persistent Join (re-join if kicked). - * AutoJoin can cease to be persistent by calling the 'disable' - * method.

- */ -public class AutoJoin extends GenericAutoService -{ - //static Logger log = Logger.getLogger(AutoJoin.class); - - private String channel = null; - private String key = null; - private TimerTaskCommand joinTimerTask = null; - private long joinTimerTaskDelay = 10*1000; - - public AutoJoin( IRCConnection connection, String channel ) - { - this( connection, channel, null ); - } - - public AutoJoin( IRCConnection connection, String channel, String key ) - { - super( connection ); - - this.channel = channel; - this.key = key; - - enable(); - - updateState( connection.getState() ); - } - - protected void updateState( State state ) - { - - if( state == State.REGISTERED ) - performJoin(); - } - - protected void updateCommand( InCommand command_o ) - { - if( command_o instanceof KickCommand ) - { - KickCommand kickCommand = (KickCommand)command_o; - - if( kickCommand.kickedUs( getConnection().getClientState() ) ) - { - if( Channel.areEqual(kickCommand.getChannel(), channel)) - { - performJoin(); - } - else - { - // mog: TODO: Should we really join a channel for which we aren't the AutoJoin:er? - // BD: You are quite right, this AutoJoin should only worry about itself. - // getConnection().sendCommand( new JoinCommand( kickCommand.getChannel() ) ); - } - } - } - else if(command_o instanceof GenericJoinError ) - { - GenericJoinError joinErr = (GenericJoinError)command_o; - - if( Channel.areEqual( joinErr.getChannel(), channel ) ) - { - //log.debug("AutoJoin: Failed to join channel: "+joinErr.getComment()); - scheduleJoin(); - } - } - else if( command_o instanceof InviteCommand ) - { - InviteCommand invite = (InviteCommand)command_o; - if(!getConnection().getClientState().isOnChannel(invite.getChannel())) - { - performJoin(); - } - } - } - - /** - * Sets up and sends the join command. - * */ - protected synchronized void performJoin() - { - setupJoin(); - sendJoinCommand(); - } - - /** - * Performs various tasks immediatly prior to sending a join command. - * Called from performJoin. - * */ - protected void setupJoin() - { - if(joinTimerTask != null) - { - joinTimerTask.cancel(); - joinTimerTask = null; - } - } - - /** - * This method sends the actual command. Called from performJoin. - * */ - protected void sendJoinCommand() - { - getConnection().sendCommand( new JoinCommand( channel, key ) ); - } - - protected void scheduleJoin() - { - if(joinTimerTask == null || !joinTimerTask.isScheduled()) - { - joinTimerTask = new TimerTaskCommand(getConnection(), new JoinCommand(channel, key)); - //TODO back off delay on repeated retries? - getConnection().getCronManager().schedule(joinTimerTask, joinTimerTaskDelay); - } - } - - public String toString() - { - if( key == null ) - return "AutoJoin [" + channel + "]"; - return "AutoJoin [" + channel + "," + key + "]"; - } - - // END AutoResponder -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoReconnect.java b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoReconnect.java deleted file mode 100644 index 06ff33f70..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoReconnect.java +++ /dev/null @@ -1,271 +0,0 @@ -package f00f.net.irc.martyr.services; - -import java.io.IOException; - -import f00f.net.irc.martyr.IRCConnection; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.GenericAutoService; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.commands.QuitCommand; - -/** - *

AutoReconnect performs the job of reconnecting to the server, if - * the connection is terminated unexpectedly. AutoReconnect - * will try to reconnect 5 times, and then give up. If AutoReconnect - * intercepts a QUIT command before the state change that is issued by - * us (bounced back from the server) then it will not try to - * reconnect.

- * - *

Note that AutoReconnect has no play in nick negotiation, and as - * such, a failed nick negotiation does not count as a connection - * retry.

- * - *

Testing note: Does a server send a QUIT before a forceful - * removal from the network? Should AutoReconnect not intercept - * QUITs? Certainly not all servers send QUITs even when you QUIT on - * your own; this class should be put into a command-out chain as well.

- */ -public class AutoReconnect extends GenericAutoService -{ - //static Logger log = Logger.getLogger(AutoReconnect.class); - - private int attempt; - private int maxAttempts; - private int sleepTime; - private boolean disableOnQuit; - - // How many times to try reconnecting? - public static final int DEFAULT_MAX_ATTEMPTS = 5; - // TODO This is a rather simplistic method, personally I would like to - // see a version of this class that implements a backoff algorithm. - - // If we tried to connect, but failed, how long do we wait until we - // try again (ms)? - public static final int DEFAULT_CONNECT_SLEEPTIME = 1000; - - // If we get a QUIT command from the server notifying us that we have - // QUIT, then self-disable so that we don't reconnect. - public static final boolean DEFAULT_DISABLE_ON_QUIT = true; - - /** - * @param connection The IRCConnection - * @param maxAttempts The number of tries to do before giving up - * @param sleepBetween Milliseconds to sleep between retries - * @param disableOnQuit Automatically disable on quit event - */ - public AutoReconnect( IRCConnection connection, int maxAttempts, - int sleepBetween, boolean disableOnQuit ) - { - super( connection ); - - this.disableOnQuit = disableOnQuit; - this.maxAttempts = maxAttempts; - this.sleepTime = sleepBetween; - this.attempt = 0; - - enable(); - } - - public AutoReconnect( IRCConnection connection, int maxAttempts, - int sleepBetween ) - { - this( connection, maxAttempts, sleepBetween, DEFAULT_DISABLE_ON_QUIT ); - } - - /** - * Initializes with reasonable defaults. - * - * @param connection Connection we are associated with - */ - public AutoReconnect( IRCConnection connection ) - { - this( connection, DEFAULT_MAX_ATTEMPTS, DEFAULT_CONNECT_SLEEPTIME ); - } - - /** - * Attempts to connect, returning only when a connection has been made - * or repeated connections have failed. - * - * @param server Server to connect to - * @param port Port to connect to - * */ - public void go( String server, int port ) - { - doConnectionLoop( server, port ); - } - - /** - * Attempts a single connection to the server. The connection is done - * by asking the client state what server and port we are supposed to - * be connected to, and then calling IRCConnection.connect(...). - * - * @throws IOException if we could not connect successfully - * */ - protected void connect() - throws IOException - { - ClientState cstate = getConnection().getClientState(); - connect( cstate.getServer(), cstate.getPort() ); - } - - /** - * Attempts a single connection to the server. - * - * @param server Server to connect to - * @param port Port to connect to - * @throws IOException if we could not connect successfully - * */ - protected void connect( String server, int port ) - throws IOException - { - getConnection().connect( server, port ); - } - - protected void updateState( State state ) - { - //log.debug("AutoReconnect: Update with state " + state); - if( state == State.UNCONNECTED ) - { - // This should only happen if we were connected and then - // disconnected. Try connecting. - - // failedToConnect() prevents insane-reconnecting loop if - // we never registered, however, it introduces a delay if we - // were registered properly previously - if (failedToConnect(null)) - doConnectionLoop(); - } else if( state == State.REGISTERED ) { - this.attempt = 0; - } - - //log.debug("AutoReconnect: Returned from " + state); - } - - /** - * Calls connect() followed by failedToConnect(...) until a connection - * is made. Gets the server and port from the client state, implying - * that a connection was already attempted before. - * */ - protected void doConnectionLoop() - { - // Tell called proc to use client state info - doConnectionLoop( null, -1 ); - } - - /** - * Calls connect() followed by failedToConnect(...) until a connection - * is made, or the service is disabled. - * - * @param server Server to connect to - * @param port Port to connect to - * */ - protected void doConnectionLoop( String server, int port ) - { - boolean keeptrying = true; - - while( keeptrying && enabled ) - { - Exception error = null; - try - { - if( server == null ) - { - // Try getting the info from the client state - connect(); - } - else - { - connect( server, port ); - } - keeptrying = false; - } - catch( Exception e ) - { - error = e; - keeptrying = true; - } - - if( keeptrying ) - { - keeptrying = failedToConnect( error ); - } - } - } - - /** - * Called when the final failure has occurred. Default implementation - * does nothing. - * */ - protected void finalFailure() - { - //log.debug("AutoReconnect: Final failure."); - this.attempt = 0; - } - - /** - * Called when a failure to connect occurs. This method should do - * whatever needs to be done between connection attempts; usually this - * will be sleeping the current thread and checking if we should stop - * trying to reconnect. - * - * @param error Exception that caused the failure - * @return true if another attempt at connecting should occur - * */ - protected boolean failedToConnect( Exception error ) - { - //log.debug("AutoReconnect: Error connecting: " + error); - - this.attempt++; - - // abort if we've tried too many times - if( attempt >= maxAttempts ) - { - //log.debug("AutoReconnect: Tried " + attempt + " times, giving up."); - finalFailure(); - return false; - } - - // Well, try again damnit! - // Sleep for a bit first. - try - { - Thread.sleep( sleepTime ); - } - catch( InterruptedException ie ) - { - // And we're going to do what? - return false; - } - - return true; - } - - /** - * AutoReconnect will disable itself if it sees a quit command - * generated by returned from the server. This usually happens just - * before the server terminates the connection. Note that this would - * really be better if we could intercept messages on their way out, - * but Martyr doesn't do that. - */ - protected void updateCommand( InCommand command ) - { - if( disableOnQuit - && command instanceof QuitCommand - && ((QuitCommand)command).isOurQuit(getConnection().getClientState()) ) - { - //log.debug("AutoReconnect: Disabling due to receiving own QUIT."); - disable(); - } - } - - public String toString() - { - return "AutoReconnect [" + attempt + "]"; - } - -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoRegister.java b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoRegister.java deleted file mode 100644 index f0cec08ba..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoRegister.java +++ /dev/null @@ -1,289 +0,0 @@ -package f00f.net.irc.martyr.services; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import f00f.net.irc.martyr.IRCConnection; -import f00f.net.irc.martyr.InCommand; -import f00f.net.irc.martyr.GenericAutoService; -import f00f.net.irc.martyr.State; -import f00f.net.irc.martyr.TimerTaskCommand; -import f00f.net.irc.martyr.clientstate.ClientState; -import f00f.net.irc.martyr.commands.NickCommand; -import f00f.net.irc.martyr.commands.UserCommand; -import f00f.net.irc.martyr.commands.PassCommand; -import f00f.net.irc.martyr.errors.NickInUseError; -import f00f.net.irc.martyr.util.FullNick; -import java.util.logging.Logger; - -/** - *

AutoRegister performs the task of registering the user with the server - * once connected, including finding an appropriate nickname to use if the - * desired one is taken.

- * - *

AutoRegister's default behaviour is to send the provided nickname. If it - * receives an ERR_NICKNAMEINUSE while unregistered, AutoRegister will try - * again, with an _ appended to the nick. If this fails five times, - * AutoRegister will ask the IRCConnection to disconnect(). Note that if it - * fails to connect it remains enabled, so that if IRCConnection.connect() is - * called, it will re-try the same 5 NICKs.

- * - *

This default behaviour can be overridden by subclassing AutoRegister and - * overriding the getNickIterator( String baseNick ) method. It returns an - * instance of the java.util.Iterator interface which supplies nicknames (each - * object retreived from the Iterator is presumed to be a String). - * AutoRegister will iterate through the nickname list until there are no more - * items, at which point it will stop. For simple tasks such as providing a - * custom way to form new nicknames, overriding getNickIterator is - * sufficient.

- * - *

AutoRegister will add itself as a state observer and as a command - * observer. It needs to receive the error.NickInUseError command so that - * it can re-try the registration, and it needs to detect when we - * transition into the UNREGISTERED state.

- * - *

AutoRegister should be created before the IRCConnection.connect() - * is called. AutoRegister can be disabled by calling the 'disable()' - * method at any time. This simply removes AutoRegister as an - * observer for the state and commands.

- * - */ -public class AutoRegister extends GenericAutoService -{ - static Logger log = Logger.getLogger(AutoRegister.class.getName()); - - // I've lost track of why the timer stuff was in here. I think the - // original purpose was to make AutoRegister take control of the nick - // more *after* registration occurred. This code is now causing so - // many problems *before* registration, that I think it may need to be - // pulled out. Maybe time to bring a "Manager" service into the - // fold? - private long nickTimerTaskDelay = 10*1000; - private TimerTaskCommand nickTimerTask; - - // Kept so it can be passed to getNickIterator() - private String originalNick; - // Used to set the client state once we register properly. - private String lastTryNick = null; - // Passed to the server on login - private String user; - private String name; - private String pass; - // Our list of nicks. - private Iterator nickIterator = null; - // attempt is only used for the debug output. - private int attempt = 0; - - public static final int MAX_ATTEMPTS = 5; - - public AutoRegister( IRCConnection connection, String nick, - String user, String name ) - { - super( connection ); - - this.originalNick = nick; - this.user = user; - this.name = name; - this.pass = null; - - enable(); - } - - public AutoRegister( IRCConnection connection, String nick, - String user, String name, String pass) - { - super( connection ); - - this.originalNick = nick; - this.user = user; - this.name = name; - this.pass = pass; - - enable(); - } - - - /** - *

This method supplies an Iterator that generates nicknames. Each successive - * failed attempt to login to the server with a nickname will be met with a new - * try using the next nickname in the iterator. When there are no more - * nicknames in the Iterator, AutoRegister gives up. Defining the Iterator as - * an anonymous class works well.

- * - *

The iterator should iterate over String objects.

- * - * @param baseNick The nickname passed into the constructor. - * @return Iterator over other attempts of nicks to try - */ - protected Iterator getNickIterator( final String baseNick ) - { - // This is simple and clean.. define the nick generation scheme as an - // anonymous class. - return new UnderscoreIterator(baseNick); - } - - private static class UnderscoreIterator implements Iterator - { - int count = 1; - String nick; - - public UnderscoreIterator( String base ) - { - this.nick = base; - } - - public boolean hasNext() - { - return count <= MAX_ATTEMPTS; - } - - public Object next() - { - if( hasNext() ) - { - String result = nick; - - // Set up the next round - nick = nick + "_"; - ++count; - - // return the value for this round. - return result; - } - else - { - throw new NoSuchElementException("No more nicknames"); - } - } - - public void remove() - { - throw new UnsupportedOperationException(); - } - } - - protected void updateState( State state ) - { - //log.debug("AutoRegister: Update with state " + state); - if( state == State.UNREGISTERED ) - { - // We need to do some registerin'! - nickIterator = getNickIterator( originalNick ); - attempt = 0; - doRegister(); - } - else if( state == State.REGISTERED ) - { - // We need to update the client state. - ClientState clientState = getConnection().getClientState(); - clientState.setNick( new FullNick( lastTryNick ) ); - clientState.setName( name ); - clientState.setUser( user ); - clientState.setPass( pass ); - } - - //log.debug("AutoRegister: Returned from " + state); - } - - protected void updateCommand( InCommand command ) - { - // First, check the state, because if we are already registered - // then none of this matters. - //if( getConnection().getState() == State.REGISTERED ) - //{ - // // We're registered. - // // No reason to continue. - // return; - //} - - if( command instanceof NickInUseError) - { - // If we get an error, then try another nick - NickInUseError nickErr = (NickInUseError)command; - if(nickErr.getNick().getNick().equals(originalNick)) - { - cancelNickAttempt(); // We don't want more than one of these - - scheduleNickAttempt(); - } - if(getConnection().getState() == State.UNREGISTERED ) - { - // re-register. - doRegister(); - } - } - else if( command instanceof NickCommand ) - { - // If we get a nick... then cancel a pending change - NickCommand nickCmd = (NickCommand)command; - if( nickCmd.getOldNick().equalsIgnoreCase( originalNick ) ) - { - cancelNickAttempt(); - } - } - } - - /** - * - */ - private void scheduleNickAttempt() - { - if( getConnection().getState().equals(State.REGISTERED)) - { - // We're already connected. - // We're short-circuiting - return; - } - if(nickTimerTask == null || !nickTimerTask.isScheduled()) - { - nickTimerTask = new TimerTaskCommand(getConnection(), new NickCommand(originalNick)); - //TODO back off delay on repeated retries? - getConnection().getCronManager().schedule(nickTimerTask, nickTimerTaskDelay); - } - } - - private void cancelNickAttempt() - { - if(nickTimerTask != null && nickTimerTask.isScheduled()) - { - nickTimerTask.cancel(); - } - } - - private void doRegister() - { - if( getConnection().getState() != State.UNREGISTERED ) - { - log.severe("AutoRegister: Tried to register but we are not UNREGISTERED"); - return; - } - - if( ! nickIterator.hasNext() ) - { - log.info("AutoRegister: Failed to register."); - getConnection().disconnect(); - return; - } - - lastTryNick = (String)nickIterator.next(); - ++attempt; - log.info("AutoRegister: Trying to register as " + lastTryNick); - - if (pass != null) { - getConnection().sendCommand( new PassCommand( pass )); - } - getConnection().sendCommand( new NickCommand( lastTryNick ) ); - getConnection().sendCommand( new UserCommand( user, name, getConnection() ) ); - } - - public String toString() - { - return "AutoRegister [" + attempt + "]"; - } - - // END AutoRegister -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoResponder.java b/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoResponder.java deleted file mode 100644 index 08f3a7f29..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/services/AutoResponder.java +++ /dev/null @@ -1,82 +0,0 @@ -package f00f.net.irc.martyr.services; - -import java.util.Observable; -import java.util.Observer; - -import f00f.net.irc.martyr.IRCConnection; -import f00f.net.irc.martyr.commands.ChannelModeCommand; -import f00f.net.irc.martyr.commands.JoinCommand; -import f00f.net.irc.martyr.commands.PingCommand; -import f00f.net.irc.martyr.commands.PongCommand; - -/** - * AutoResponder is where commands that should be auto-responded (such - * as PING-PONG) should go. - */ -public class AutoResponder implements Observer -{ - - private IRCConnection connection; - private boolean enabled = false; - - public AutoResponder( IRCConnection connection ) - { - this.connection = connection; - enable(); - } - - public void enable() - { - if( enabled ) - return; - - connection.addCommandObserver( this ); - enabled = true; - } - - public void disable() - { - if( !enabled ) - return; - - connection.removeCommandObserver( this ); - enabled = false; - } - - /** - * Does the work of figuring out what to respond to. - * If a PING is received, send a PONG. If we JOIN a channel, send a - * request for modes. - * */ - public void update( Observable observer, Object updated ) - { - - if( updated instanceof PingCommand ) - { - // We need to do some pongin'! - PingCommand ping = (PingCommand)updated; - - String response = ping.getPingSource(); - - connection.sendCommand( new PongCommand( response ) ); - } - else if( updated instanceof JoinCommand ) - { - // Determine if we joined, and if we did, trigger a MODE discovery - // request. - JoinCommand join = (JoinCommand)updated; - - if( join.weJoined( connection.getClientState() ) ) - { - connection.sendCommand( - new ChannelModeCommand( join.getChannel() ) ); - } - } - } - - // END AutoResponder -} - - - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/util/CtcpUtil.java b/EssentialsUpdate/src/f00f/net/irc/martyr/util/CtcpUtil.java deleted file mode 100644 index ed31c46e7..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/util/CtcpUtil.java +++ /dev/null @@ -1,99 +0,0 @@ -package f00f.net.irc.martyr.util; - -import java.util.NoSuchElementException; - -public class CtcpUtil -{ - public static final char CTCP_TAG_DELIM = '\001'; - - /** - * Returns a new string ready for sending via MessageCommand. - * - * @param action Action string to create - * @return Action string ready for sending - */ - public static String makeActionString( String action ) - { - return makeCtcpString( "ACTION " + action ); - } - - public static String makeCtcpString( String s ) - { - return "" + CTCP_TAG_DELIM + s + CTCP_TAG_DELIM; - } - - /** - * Parses the string into tokens, where each token is either a - * CTCP escaped sequence or not. - */ - public static class CtcpTokenizer - { - private String str; - - public CtcpTokenizer( String in ) - { - this.str = in; - } - - public boolean isNextACtcp() - { - return str.charAt(0) == CTCP_TAG_DELIM; - } - - public boolean hasNext() - { - return !str.equals(""); - } - - public String next() - { - return nextToken(); - } - public String nextToken() - { - if( !hasNext() ) - { - throw new NoSuchElementException(); - } - - int pos = str.indexOf( CTCP_TAG_DELIM, 1 ); - String result; - if( isNextACtcp() ) - { - if( pos < 0 ) - { - // Error? Well, whatever, return the rest of the - // string. - result = str.substring( 1 ); - str = ""; - return result; - } - else - { - // ^Aour string^A(rest of string) - // Lose both ^A - result = str.substring( 1, pos ); - str = str.substring( pos + 1 ); - return result; - } - } - else - { - // Not a CTCP - if( pos < 0 ) - { - result = str; - str = ""; - return result; - } - else - { - result = str.substring( 0, pos ); - str = str.substring( pos ); - return result; - } - } - } - } -} - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/util/FullNick.java b/EssentialsUpdate/src/f00f/net/irc/martyr/util/FullNick.java deleted file mode 100644 index c83cd98d4..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/util/FullNick.java +++ /dev/null @@ -1,159 +0,0 @@ -package f00f.net.irc.martyr.util; - -import java.util.StringTokenizer; - -/** - * Parses out a full nick (ex: sork<exclaimation>sork<at>f00f.net) and stores it for - * use. It also provides a consistent hashing method. - */ -public class FullNick -{ - - private String nick; - private String user; - private String remotehost; - - private String original; - - public FullNick( String original ) - { - this.original = original; - parse( original ); - } - - - /** - * It can't deal with parameters that have no '!'. When given a parameter with - * no '!', it simply places the entire string into the 'nick' field. FullNick - * is intended to be immutable. - * - * TODO: Should this enforce proper nick syntax? - * @param original Original nick we will parse - */ - private void parse( String original ) - { - if( original == null ) - return; - - StringTokenizer tokens = new StringTokenizer( original, "!", false ); - - nick = tokens.nextToken(); - - if( tokens.hasMoreTokens() ) - { - user = tokens.nextToken("@"); - if( user.charAt(0) == '!' ) - user = user.substring(1); - } - - if( tokens.hasMoreTokens() ) - { - remotehost = tokens.nextToken(""); - if( remotehost.charAt(0) == '@' ) - remotehost = remotehost.substring(1); - } - } - - public String getNick() - { - return nick; - } - - public String getUser() - { - return user; - } - - public String getHost() - { - return remotehost; - } - - public String getSource() - { - //return nick+"!"+user+"@"+remotehost; - return original; - } - - - public int hashCode() - { - if( nick == null ) - return 0; - - return nick.hashCode(); - } - - /** - * Performs case insesitive equals on the nicks only. Does not strip - * off any leading @ or +. ({ == [ and ] == } and | == \) It appears - * that servers are not RFC complient on this, so we will not as well. - * - * @param nick Nick to compare this nick with - * @return True or false of nick is the same - */ - - public boolean equals( String nick ) - { - if( nick == null ) - return false; - - return nick.equalsIgnoreCase( this.nick ); - } - - public boolean equals( FullNick nick ) - { - if( nick == null ) - return false; - return equals( nick.getNick() ); - } - - public boolean equals( Object object ) - { - if( object instanceof FullNick ) - return equals( (FullNick)object ); - return false; - } - - /** - * @return the nick part - * */ - public String toString() - { - return nick; - } - - /** - * Unit test. - * - * @param args Args passed to program - */ - public static void main( String args[] ) - { - - FullNick nick = new FullNick( args[0] ); - - System.out.println( nick.getNick() ); - System.out.println( nick.getUser() ); - System.out.println( nick.getHost() ); - System.out.println( nick.getSource() ); - - if( args.length > 1 ) - { - - FullNick nick2 = new FullNick( args[1] ); - - System.out.println( "" ); - System.out.println( nick2.getNick() ); - System.out.println( nick2.getUser() ); - System.out.println( nick2.getHost() ); - System.out.println( nick2.getSource() ); - - System.out.println( nick2.equals( nick ) ? "Equal." : "Not equal." ); - - } - } - -} - - diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/util/IRCStringUtils.java b/EssentialsUpdate/src/f00f/net/irc/martyr/util/IRCStringUtils.java deleted file mode 100644 index 3b4fa6075..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/util/IRCStringUtils.java +++ /dev/null @@ -1,90 +0,0 @@ -package f00f.net.irc.martyr.util; - -import java.text.CharacterIterator; -import java.text.StringCharacterIterator; -import java.util.ArrayList; -import java.util.regex.Pattern; -import java.util.regex.Matcher; - -/** - * @author Daniel Henninger - */ -public class IRCStringUtils -{ - - /** - * Returns the message with all control characters stripped from it. - * - * @param msg Message to remove control chars from. - * @return Stripped form of message. - */ - public static String stripControlChars(String msg) - { - Pattern pa = Pattern.compile("\u0003\\p{Digit}\\p{Digit}"); - Matcher ma = pa.matcher(msg); - Pattern pb = Pattern.compile("\\p{Cntrl}"); - Matcher mb = pb.matcher(ma.replaceAll("")); - return mb.replaceAll(""); - } - - /** - * Returns the message with all formatting characters converted into associated html characters. - * - * TODO: Should actually parse colors. - * @param msg Message to convert to HTML format. - * @return Message in HTML format. - */ - public static String convertToHTML(String msg) - { - CharacterIterator ci = new StringCharacterIterator(msg); - String htmlStr = ""; - ArrayList formatList = new ArrayList(); - for (char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) { - if (c == '\u0002') { - if (formatList.contains("
")) { - formatList.remove(""); - htmlStr += ""; - } - else { - formatList.add(""); - htmlStr += ""; - } - } - else if (c == '\u001F') { - if (formatList.contains("")) { - formatList.remove(""); - htmlStr += ""; - } - else { - formatList.add(""); - htmlStr += ""; - } - } - else if (c == '\u0016') { - if (formatList.contains("")) { - formatList.remove(""); - htmlStr += ""; - } - else { - formatList.add(""); - htmlStr += ""; - } - } - else if (c == '\u000F' || c == '\u0015') { - for (String f : formatList) { - htmlStr += f; - } - formatList.clear(); - } - else { - htmlStr += c; - } - } - for (String f : formatList) { - htmlStr += f; - } - formatList.clear(); - return stripControlChars(htmlStr); - } - -} diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/util/ParameterIterator.java b/EssentialsUpdate/src/f00f/net/irc/martyr/util/ParameterIterator.java deleted file mode 100644 index d1e2c8507..000000000 --- a/EssentialsUpdate/src/f00f/net/irc/martyr/util/ParameterIterator.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Original author: Ben Damm - * Changes by: Mog - * - Fixed bug with substring handling - * */ -package f00f.net.irc.martyr.util; - - -import java.util.Iterator; -import java.util.NoSuchElementException; - -//TODO: Unit test - -/** - * This class iterates over the parameter string of an IRC command, - * returning each parameter in order as next() is called. This class - * also knows about the ":" parameters, which is the large string at - * the end of most commands, and treats it specially. - */ -public class ParameterIterator implements Iterator -{ - //static Logger log = Logger.getLogger(ParameterIterator.class); - - private String paramStr; - private int position; - private String last = null; - - public ParameterIterator( String paramStr ) - { - //log.debug("ParameterIterator: Params: `" + paramStr + "'"); - // We don't check for null here because hasNext is the place - // to do it, according to the definition for Iterator. - // next() should throw an exception. - if( paramStr != null ) - { - this.paramStr = paramStr.trim(); - position = 0; - } - else - { - this.paramStr = null; - position = -1; - } - } - - /** - * @return true if there are more parameters, and false - * otherwise. - */ - public boolean hasNext() - { - if( paramStr == null ) - return false; - - return position < paramStr.length(); - } - - /** - * @throws NoSuchElementException if there are no more params - * @return true if the next parameter is also the ":" parameter. - * */ - public boolean nextIsLast() - { - if( ! hasNext() ) - { - throw new NoSuchElementException("No more parameters."); - } - return paramStr.charAt(position) == ':'; - } - - /** - * @throws NoSuchElementException if there are no more params - * */ - public Object next() - { - if( ! hasNext() ) - { - throw new NoSuchElementException("No more parameters."); - } - - // If : is the first char, the rest of the string is a - // parameter. - if( paramStr.charAt(position) == ':' ) - { - String result = paramStr.substring(position + 1); - position = paramStr.length(); - last = result; - return result; - } - - int spaceIndex = paramStr.indexOf( ' ', position ); - // We can't have a space after the last parameter, it gets - // trimmed in the constructor. Also, we can't have only - // spaces, so we don't need to check for -1. Finally, we are - // guaranteed to have a space before the colon, so we don't - // have to do any checking at all! - - String result = paramStr.substring( position, spaceIndex ); - position = spaceIndex + 1; - return result; - } - - /** - * Forwards the iterator to the last element and returns it. The - * "last" parameter should be the ":" parameter. - * - * @return Last parameter - * */ - public String last() - { - while( hasNext() ) - next(); - - return last; - } - - public void remove() - { - // hmm, nah. This can be implemented some other time. - throw new UnsupportedOperationException( "Remove on the parameters? Why?" ); - } -} - - diff --git a/EssentialsUpdate/src/org/jibble/pircbot/Colors.java b/EssentialsUpdate/src/org/jibble/pircbot/Colors.java new file mode 100755 index 000000000..c763cba22 --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/Colors.java @@ -0,0 +1,293 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + + +package org.jibble.pircbot; + +/** + * The Colors class provides several static fields and methods that you may + * find useful when writing an IRC Bot. + *

+ * This class contains constants that are useful for formatting lines + * sent to IRC servers. These constants allow you to apply various + * formatting to the lines, such as colours, boldness, underlining + * and reverse text. + *

+ * The class contains static methods to remove colours and formatting + * from lines of IRC text. + *

+ * Here are some examples of how to use the contants from within a + * class that extends PircBot and imports org.jibble.pircbot.*; + * + *

 sendMessage("#cs", Colors.BOLD + "A bold hello!");
+ *     A bold hello!
+ * sendMessage("#cs", Colors.RED + "Red" + Colors.NORMAL + " text");
+ *     Red text
+ * sendMessage("#cs", Colors.BOLD + Colors.RED + "Bold and red");
+ *     Bold and red
+ * + * Please note that some IRC channels may be configured to reject any + * messages that use colours. Also note that older IRC clients may be + * unable to correctly display lines that contain colours and other + * control characters. + *

+ * Note that this class name has been spelt in the American style in + * order to remain consistent with the rest of the Java API. + * + * + * @since 0.9.12 + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public class Colors { + + + /** + * Removes all previously applied color and formatting attributes. + */ + public static final String NORMAL = "\u000f"; + + + /** + * Bold text. + */ + public static final String BOLD = "\u0002"; + + + /** + * Underlined text. + */ + public static final String UNDERLINE = "\u001f"; + + + /** + * Reversed text (may be rendered as italic text in some clients). + */ + public static final String REVERSE = "\u0016"; + + + /** + * White coloured text. + */ + public static final String WHITE = "\u000300"; + + + /** + * Black coloured text. + */ + public static final String BLACK = "\u000301"; + + + /** + * Dark blue coloured text. + */ + public static final String DARK_BLUE = "\u000302"; + + + /** + * Dark green coloured text. + */ + public static final String DARK_GREEN = "\u000303"; + + + /** + * Red coloured text. + */ + public static final String RED = "\u000304"; + + + /** + * Brown coloured text. + */ + public static final String BROWN = "\u000305"; + + + /** + * Purple coloured text. + */ + public static final String PURPLE = "\u000306"; + + + /** + * Olive coloured text. + */ + public static final String OLIVE = "\u000307"; + + + /** + * Yellow coloured text. + */ + public static final String YELLOW = "\u000308"; + + + /** + * Green coloured text. + */ + public static final String GREEN = "\u000309"; + + + /** + * Teal coloured text. + */ + public static final String TEAL = "\u000310"; + + + /** + * Cyan coloured text. + */ + public static final String CYAN = "\u000311"; + + + /** + * Blue coloured text. + */ + public static final String BLUE = "\u000312"; + + + /** + * Magenta coloured text. + */ + public static final String MAGENTA = "\u000313"; + + + /** + * Dark gray coloured text. + */ + public static final String DARK_GRAY = "\u000314"; + + + /** + * Light gray coloured text. + */ + public static final String LIGHT_GRAY = "\u000315"; + + + /** + * This class should not be constructed. + */ + private Colors() { + + } + + + /** + * Removes all colours from a line of IRC text. + * + * @since PircBot 1.2.0 + * + * @param line the input text. + * + * @return the same text, but with all colours removed. + */ + public static String removeColors(String line) { + int length = line.length(); + StringBuffer buffer = new StringBuffer(); + int i = 0; + while (i < length) { + char ch = line.charAt(i); + if (ch == '\u0003') { + i++; + // Skip "x" or "xy" (foreground color). + if (i < length) { + ch = line.charAt(i); + if (Character.isDigit(ch)) { + i++; + if (i < length) { + ch = line.charAt(i); + if (Character.isDigit(ch)) { + i++; + } + } + // Now skip ",x" or ",xy" (background color). + if (i < length) { + ch = line.charAt(i); + if (ch == ',') { + i++; + if (i < length) { + ch = line.charAt(i); + if (Character.isDigit(ch)) { + i++; + if (i < length) { + ch = line.charAt(i); + if (Character.isDigit(ch)) { + i++; + } + } + } + else { + // Keep the comma. + i--; + } + } + else { + // Keep the comma. + i--; + } + } + } + } + } + } + else if (ch == '\u000f') { + i++; + } + else { + buffer.append(ch); + i++; + } + } + return buffer.toString(); + } + + + /** + * Remove formatting from a line of IRC text. + * + * @since PircBot 1.2.0 + * + * @param line the input text. + * + * @return the same text, but without any bold, underlining, reverse, etc. + */ + public static String removeFormatting(String line) { + int length = line.length(); + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < length; i++) { + char ch = line.charAt(i); + if (ch == '\u000f' || ch == '\u0002' || ch == '\u001f' || ch == '\u0016') { + // Don't add this character. + } + else { + buffer.append(ch); + } + } + return buffer.toString(); + } + + + /** + * Removes all formatting and colours from a line of IRC text. + * + * @since PircBot 1.2.0 + * + * @param line the input text. + * + * @return the same text, but without formatting and colour characters. + * + */ + public static String removeFormattingAndColors(String line) { + return removeFormatting(removeColors(line)); + } + +} diff --git a/EssentialsUpdate/src/org/jibble/pircbot/InputThread.java b/EssentialsUpdate/src/org/jibble/pircbot/InputThread.java new file mode 100755 index 000000000..1c30ad815 --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/InputThread.java @@ -0,0 +1,169 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + + +package org.jibble.pircbot; + +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * A Thread which reads lines from the IRC server. It then + * passes these lines to the PircBot without changing them. + * This running Thread also detects disconnection from the server + * and is thus used by the OutputThread to send lines to the server. + * + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public class InputThread extends Thread { + + /** + * The InputThread reads lines from the IRC server and allows the + * PircBot to handle them. + * + * @param bot An instance of the underlying PircBot. + * @param breader The BufferedReader that reads lines from the server. + * @param bwriter The BufferedWriter that sends lines to the server. + */ + InputThread(PircBot bot, Socket socket, BufferedReader breader, BufferedWriter bwriter) { + _bot = bot; + _socket = socket; + _breader = breader; + _bwriter = bwriter; + this.setName(this.getClass() + "-Thread"); + } + + + /** + * Sends a raw line to the IRC server as soon as possible, bypassing the + * outgoing message queue. + * + * @param line The raw line to send to the IRC server. + */ + void sendRawLine(String line) { + OutputThread.sendRawLine(_bot, _bwriter, line); + } + + + /** + * Returns true if this InputThread is connected to an IRC server. + * The result of this method should only act as a rough guide, + * as the result may not be valid by the time you act upon it. + * + * @return True if still connected. + */ + boolean isConnected() { + return _isConnected; + } + + + /** + * Called to start this Thread reading lines from the IRC server. + * When a line is read, this method calls the handleLine method + * in the PircBot, which may subsequently call an 'onXxx' method + * in the PircBot subclass. If any subclass of Throwable (i.e. + * any Exception or Error) is thrown by your method, then this + * method will print the stack trace to the standard output. It + * is probable that the PircBot may still be functioning normally + * after such a problem, but the existance of any uncaught exceptions + * in your code is something you should really fix. + */ + public void run() { + try { + boolean running = true; + while (running) { + try { + String line = null; + while ((line = _breader.readLine()) != null) { + try { + _bot.handleLine(line); + } + catch (Throwable t) { + // Stick the whole stack trace into a String so we can output it nicely. + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + t.printStackTrace(pw); + pw.flush(); + StringTokenizer tokenizer = new StringTokenizer(sw.toString(), "\r\n"); + synchronized (_bot) { + _bot.log("### Your implementation of PircBot is faulty and you have"); + _bot.log("### allowed an uncaught Exception or Error to propagate in your"); + _bot.log("### code. It may be possible for PircBot to continue operating"); + _bot.log("### normally. Here is the stack trace that was produced: -"); + _bot.log("### "); + while (tokenizer.hasMoreTokens()) { + _bot.log("### " + tokenizer.nextToken()); + } + } + } + } + if (line == null) { + // The server must have disconnected us. + running = false; + } + } + catch (InterruptedIOException iioe) { + // This will happen if we haven't received anything from the server for a while. + // So we shall send it a ping to check that we are still connected. + this.sendRawLine("PING " + (System.currentTimeMillis() / 1000)); + // Now we go back to listening for stuff from the server... + } + } + } + catch (Exception e) { + // Do nothing. + } + + // If we reach this point, then we must have disconnected. + try { + _socket.close(); + } + catch (Exception e) { + // Just assume the socket was already closed. + } + + if (!_disposed) { + _bot.log("*** Disconnected."); + _isConnected = false; + _bot.onDisconnect(); + } + + } + + + /** + * Closes the socket without onDisconnect being called subsequently. + */ + public void dispose () { + try { + _disposed = true; + _socket.close(); + } + catch (Exception e) { + // Do nothing. + } + } + + private PircBot _bot = null; + private Socket _socket = null; + private BufferedReader _breader = null; + private BufferedWriter _bwriter = null; + private boolean _isConnected = true; + private boolean _disposed = false; + + public static final int MAX_LINE_LENGTH = 512; + +} diff --git a/EssentialsUpdate/src/org/jibble/pircbot/IrcException.java b/EssentialsUpdate/src/org/jibble/pircbot/IrcException.java new file mode 100755 index 000000000..d07d8a956 --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/IrcException.java @@ -0,0 +1,35 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + +package org.jibble.pircbot; + +/** + * An IrcException class. + * + * @since 0.9 + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public class IrcException extends Exception { + + /** + * Constructs a new IrcException. + * + * @param e The error message to report. + */ + public IrcException(String e) { + super(e); + } + +} diff --git a/EssentialsUpdate/src/org/jibble/pircbot/NickAlreadyInUseException.java b/EssentialsUpdate/src/org/jibble/pircbot/NickAlreadyInUseException.java new file mode 100755 index 000000000..33887be34 --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/NickAlreadyInUseException.java @@ -0,0 +1,38 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + + +package org.jibble.pircbot; + +/** + * A NickAlreadyInUseException class. This exception is + * thrown when the PircBot attempts to join an IRC server + * with a user name that is already in use. + * + * @since 0.9 + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public class NickAlreadyInUseException extends IrcException { + + /** + * Constructs a new IrcException. + * + * @param e The error message to report. + */ + public NickAlreadyInUseException(String e) { + super(e); + } + +} diff --git a/EssentialsUpdate/src/org/jibble/pircbot/OutputThread.java b/EssentialsUpdate/src/org/jibble/pircbot/OutputThread.java new file mode 100755 index 000000000..86ac404d2 --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/OutputThread.java @@ -0,0 +1,105 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + + +package org.jibble.pircbot; + +import java.io.*; +import java.net.*; + +/** + * A Thread which is responsible for sending messages to the IRC server. + * Messages are obtained from the outgoing message queue and sent + * immediately if possible. If there is a flood of messages, then to + * avoid getting kicked from a channel, we put a small delay between + * each one. + * + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public class OutputThread extends Thread { + + + /** + * Constructs an OutputThread for the underlying PircBot. All messages + * sent to the IRC server are sent by this OutputThread to avoid hammering + * the server. Messages are sent immediately if possible. If there are + * multiple messages queued, then there is a delay imposed. + * + * @param bot The underlying PircBot instance. + * @param outQueue The Queue from which we will obtain our messages. + */ + OutputThread(PircBot bot, Queue outQueue) { + _bot = bot; + _outQueue = outQueue; + this.setName(this.getClass() + "-Thread"); + } + + + /** + * A static method to write a line to a BufferedOutputStream and then pass + * the line to the log method of the supplied PircBot instance. + * + * @param bot The underlying PircBot instance. + * @param out The BufferedOutputStream to write to. + * @param line The line to be written. "\r\n" is appended to the end. + * @param encoding The charset to use when encoing this string into a + * byte array. + */ + static void sendRawLine(PircBot bot, BufferedWriter bwriter, String line) { + if (line.length() > bot.getMaxLineLength() - 2) { + line = line.substring(0, bot.getMaxLineLength() - 2); + } + synchronized(bwriter) { + try { + bwriter.write(line + "\r\n"); + bwriter.flush(); + bot.log(">>>" + line); + } + catch (Exception e) { + // Silent response - just lose the line. + } + } + } + + + /** + * This method starts the Thread consuming from the outgoing message + * Queue and sending lines to the server. + */ + public void run() { + try { + boolean running = true; + while (running) { + // Small delay to prevent spamming of the channel + Thread.sleep(_bot.getMessageDelay()); + + String line = (String) _outQueue.next(); + if (line != null) { + _bot.sendRawLine(line); + } + else { + running = false; + } + } + } + catch (InterruptedException e) { + // Just let the method return naturally... + } + } + + private PircBot _bot = null; + private Queue _outQueue = null; + +} diff --git a/EssentialsUpdate/src/org/jibble/pircbot/PircBot.java b/EssentialsUpdate/src/org/jibble/pircbot/PircBot.java new file mode 100755 index 000000000..a5f049cde --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/PircBot.java @@ -0,0 +1,2808 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + + +package org.jibble.pircbot; + +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * PircBot is a Java framework for writing IRC bots quickly and easily. + *

+ * It provides an event-driven architecture to handle common IRC + * events, flood protection, DCC support, ident support, and more. + * The comprehensive logfile format is suitable for use with pisg to generate + * channel statistics. + *

+ * Methods of the PircBot class can be called to send events to the IRC server + * that it connects to. For example, calling the sendMessage method will + * send a message to a channel or user on the IRC server. Multiple servers + * can be supported using multiple instances of PircBot. + *

+ * To perform an action when the PircBot receives a normal message from the IRC + * server, you would override the onMessage method defined in the PircBot + * class. All onXYZ methods in the PircBot class are automatically called + * when the event XYZ happens, so you would override these if you wish + * to do something when it does happen. + *

+ * Some event methods, such as onPing, should only really perform a specific + * function (i.e. respond to a PING from the server). For your convenience, such + * methods are already correctly implemented in the PircBot and should not + * normally need to be overridden. Please read the full documentation for each + * method to see which ones are already implemented by the PircBot class. + *

+ * Please visit the PircBot homepage at + * http://www.jibble.org/pircbot.php + * for full revision history, a beginners guide to creating your first PircBot + * and a list of some existing Java IRC bots and clients that use the PircBot + * framework. + * + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public abstract class PircBot implements ReplyConstants { + + + /** + * The definitive version number of this release of PircBot. + * (Note: Change this before automatically building releases) + */ + public static final String VERSION = "1.5.0"; + + + private static final int OP_ADD = 1; + private static final int OP_REMOVE = 2; + private static final int VOICE_ADD = 3; + private static final int VOICE_REMOVE = 4; + + + /** + * Constructs a PircBot with the default settings. Your own constructors + * in classes which extend the PircBot abstract class should be responsible + * for changing the default settings if required. + */ + public PircBot() {} + + + /** + * Attempt to connect to the specified IRC server. + * The onConnect method is called upon success. + * + * @param hostname The hostname of the server to connect to. + * + * @throws IOException if it was not possible to connect to the server. + * @throws IrcException if the server would not let us join it. + * @throws NickAlreadyInUseException if our nick is already in use on the server. + */ + public final synchronized void connect(String hostname) throws IOException, IrcException, NickAlreadyInUseException { + this.connect(hostname, 6667, null); + } + + + /** + * Attempt to connect to the specified IRC server and port number. + * The onConnect method is called upon success. + * + * @param hostname The hostname of the server to connect to. + * @param port The port number to connect to on the server. + * + * @throws IOException if it was not possible to connect to the server. + * @throws IrcException if the server would not let us join it. + * @throws NickAlreadyInUseException if our nick is already in use on the server. + */ + public final synchronized void connect(String hostname, int port) throws IOException, IrcException, NickAlreadyInUseException { + this.connect(hostname, port, null); + } + + + /** + * Attempt to connect to the specified IRC server using the supplied + * password. + * The onConnect method is called upon success. + * + * @param hostname The hostname of the server to connect to. + * @param port The port number to connect to on the server. + * @param password The password to use to join the server. + * + * @throws IOException if it was not possible to connect to the server. + * @throws IrcException if the server would not let us join it. + * @throws NickAlreadyInUseException if our nick is already in use on the server. + */ + public final synchronized void connect(String hostname, int port, String password) throws IOException, IrcException, NickAlreadyInUseException { + + _server = hostname; + _port = port; + _password = password; + + if (isConnected()) { + throw new IOException("The PircBot is already connected to an IRC server. Disconnect first."); + } + + // Don't clear the outqueue - there might be something important in it! + + // Clear everything we may have know about channels. + this.removeAllChannels(); + + // Connect to the server. + Socket socket = new Socket(hostname, port); + this.log("*** Connected to server."); + + _inetAddress = socket.getLocalAddress(); + + InputStreamReader inputStreamReader = null; + OutputStreamWriter outputStreamWriter = null; + if (getEncoding() != null) { + // Assume the specified encoding is valid for this JVM. + inputStreamReader = new InputStreamReader(socket.getInputStream(), getEncoding()); + outputStreamWriter = new OutputStreamWriter(socket.getOutputStream(), getEncoding()); + } + else { + // Otherwise, just use the JVM's default encoding. + inputStreamReader = new InputStreamReader(socket.getInputStream()); + outputStreamWriter = new OutputStreamWriter(socket.getOutputStream()); + } + + BufferedReader breader = new BufferedReader(inputStreamReader); + BufferedWriter bwriter = new BufferedWriter(outputStreamWriter); + + // Attempt to join the server. + if (password != null && !password.equals("")) { + OutputThread.sendRawLine(this, bwriter, "PASS " + password); + } + String nick = this.getName(); + OutputThread.sendRawLine(this, bwriter, "NICK " + nick); + OutputThread.sendRawLine(this, bwriter, "USER " + this.getLogin() + " 8 * :" + this.getVersion()); + + _inputThread = new InputThread(this, socket, breader, bwriter); + + // Read stuff back from the server to see if we connected. + String line = null; + int tries = 1; + while ((line = breader.readLine()) != null) { + + this.handleLine(line); + + int firstSpace = line.indexOf(" "); + int secondSpace = line.indexOf(" ", firstSpace + 1); + if (secondSpace >= 0) { + String code = line.substring(firstSpace + 1, secondSpace); + + if (code.equals("004")) { + // We're connected to the server. + break; + } + else if (code.equals("433")) { + if (_autoNickChange) { + tries++; + nick = getName() + tries; + OutputThread.sendRawLine(this, bwriter, "NICK " + nick); + } + else { + socket.close(); + _inputThread = null; + throw new NickAlreadyInUseException(line); + } + } + else if (code.equals("439")) { + // No action required. + } + else if (code.startsWith("5") || code.startsWith("4")) { + socket.close(); + _inputThread = null; + throw new IrcException("Could not log into the IRC server: " + line); + } + } + this.setNick(nick); + + } + + this.log("*** Logged onto server."); + + // This makes the socket timeout on read operations after 5 minutes. + // Maybe in some future version I will let the user change this at runtime. + socket.setSoTimeout(5 * 60 * 1000); + + // Now start the InputThread to read all other lines from the server. + _inputThread.start(); + + // Now start the outputThread that will be used to send all messages. + if (_outputThread == null) { + _outputThread = new OutputThread(this, _outQueue); + _outputThread.start(); + } + + this.onConnect(); + + } + + + /** + * Reconnects to the IRC server that we were previously connected to. + * If necessary, the appropriate port number and password will be used. + * This method will throw an IrcException if we have never connected + * to an IRC server previously. + * + * @since PircBot 0.9.9 + * + * @throws IOException if it was not possible to connect to the server. + * @throws IrcException if the server would not let us join it. + * @throws NickAlreadyInUseException if our nick is already in use on the server. + */ + public final synchronized void reconnect() throws IOException, IrcException, NickAlreadyInUseException{ + if (getServer() == null) { + throw new IrcException("Cannot reconnect to an IRC server because we were never connected to one previously!"); + } + connect(getServer(), getPort(), getPassword()); + } + + + /** + * This method disconnects from the server cleanly by calling the + * quitServer() method. Providing the PircBot was connected to an + * IRC server, the onDisconnect() will be called as soon as the + * disconnection is made by the server. + * + * @see #quitServer() quitServer + * @see #quitServer(String) quitServer + */ + public final synchronized void disconnect() { + this.quitServer(); + } + + + /** + * When you connect to a server and your nick is already in use and + * this is set to true, a new nick will be automatically chosen. + * This is done by adding numbers to the end of the nick until an + * available nick is found. + * + * @param autoNickChange Set to true if you want automatic nick changes + * during connection. + */ + public void setAutoNickChange(boolean autoNickChange) { + _autoNickChange = autoNickChange; + } + + /** + * Joins a channel. + * + * @param channel The name of the channel to join (eg "#cs"). + */ + public final void joinChannel(String channel) { + this.sendRawLine("JOIN " + channel); + } + + + /** + * Joins a channel with a key. + * + * @param channel The name of the channel to join (eg "#cs"). + * @param key The key that will be used to join the channel. + */ + public final void joinChannel(String channel, String key) { + this.joinChannel(channel + " " + key); + } + + + /** + * Parts a channel. + * + * @param channel The name of the channel to leave. + */ + public final void partChannel(String channel) { + this.sendRawLine("PART " + channel); + } + + + /** + * Parts a channel, giving a reason. + * + * @param channel The name of the channel to leave. + * @param reason The reason for parting the channel. + */ + public final void partChannel(String channel, String reason) { + this.sendRawLine("PART " + channel + " :" + reason); + } + + + /** + * Quits from the IRC server. + * Providing we are actually connected to an IRC server, the + * onDisconnect() method will be called as soon as the IRC server + * disconnects us. + */ + public final void quitServer() { + this.quitServer(""); + } + + + /** + * Quits from the IRC server with a reason. + * Providing we are actually connected to an IRC server, the + * onDisconnect() method will be called as soon as the IRC server + * disconnects us. + * + * @param reason The reason for quitting the server. + */ + public final void quitServer(String reason) { + this.sendRawLine("QUIT :" + reason); + } + + + /** + * Sends a raw line to the IRC server as soon as possible, bypassing the + * outgoing message queue. + * + * @param line The raw line to send to the IRC server. + */ + public final synchronized void sendRawLine(String line) { + if (isConnected()) { + _inputThread.sendRawLine(line); + } + } + + /** + * Sends a raw line through the outgoing message queue. + * + * @param line The raw line to send to the IRC server. + */ + public final synchronized void sendRawLineViaQueue(String line) { + if (line == null) { + throw new NullPointerException("Cannot send null messages to server"); + } + if (isConnected()) { + _outQueue.add(line); + } + } + + + /** + * Sends a message to a channel or a private message to a user. These + * messages are added to the outgoing message queue and sent at the + * earliest possible opportunity. + *

+ * Some examples: - + *

    // Send the message "Hello!" to the channel #cs.
+     *    sendMessage("#cs", "Hello!");
+     *    
+     *    // Send a private message to Paul that says "Hi".
+     *    sendMessage("Paul", "Hi");
+ * + * You may optionally apply colours, boldness, underlining, etc to + * the message by using the Colors class. + * + * @param target The name of the channel or user nick to send to. + * @param message The message to send. + * + * @see Colors + */ + public final void sendMessage(String target, String message) { + _outQueue.add("PRIVMSG " + target + " :" + message); + } + + + /** + * Sends an action to the channel or to a user. + * + * @param target The name of the channel or user nick to send to. + * @param action The action to send. + * + * @see Colors + */ + public final void sendAction(String target, String action) { + sendCTCPCommand(target, "ACTION " + action); + } + + + /** + * Sends a notice to the channel or to a user. + * + * @param target The name of the channel or user nick to send to. + * @param notice The notice to send. + */ + public final void sendNotice(String target, String notice) { + _outQueue.add("NOTICE " + target + " :" + notice); + } + + + /** + * Sends a CTCP command to a channel or user. (Client to client protocol). + * Examples of such commands are "PING ", "FINGER", "VERSION", etc. + * For example, if you wish to request the version of a user called "Dave", + * then you would call sendCTCPCommand("Dave", "VERSION");. + * The type of response to such commands is largely dependant on the target + * client software. + * + * @since PircBot 0.9.5 + * + * @param target The name of the channel or user to send the CTCP message to. + * @param command The CTCP command to send. + */ + public final void sendCTCPCommand(String target, String command) { + _outQueue.add("PRIVMSG " + target + " :\u0001" + command + "\u0001"); + } + + + /** + * Attempt to change the current nick (nickname) of the bot when it + * is connected to an IRC server. + * After confirmation of a successful nick change, the getNick method + * will return the new nick. + * + * @param newNick The new nick to use. + */ + public final void changeNick(String newNick) { + this.sendRawLine("NICK " + newNick); + } + + + /** + * Identify the bot with NickServ, supplying the appropriate password. + * Some IRC Networks (such as freenode) require users to register and + * identify with NickServ before they are able to send private messages + * to other users, thus reducing the amount of spam. If you are using + * an IRC network where this kind of policy is enforced, you will need + * to make your bot identify itself to NickServ before you can send + * private messages. Assuming you have already registered your bot's + * nick with NickServ, this method can be used to identify with + * the supplied password. It usually makes sense to identify with NickServ + * immediately after connecting to a server. + *

+ * This method issues a raw NICKSERV command to the server, and is therefore + * safer than the alternative approach of sending a private message to + * NickServ. The latter approach is considered dangerous, as it may cause + * you to inadvertently transmit your password to an untrusted party if you + * connect to a network which does not run a NickServ service and where the + * untrusted party has assumed the nick "NickServ". However, if your IRC + * network is only compatible with the private message approach, you may + * typically identify like so: + *

sendMessage("NickServ", "identify PASSWORD");
+ * + * @param password The password which will be used to identify with NickServ. + */ + public final void identify(String password) { + this.sendRawLine("NICKSERV IDENTIFY " + password); + } + + + /** + * Set the mode of a channel. + * This method attempts to set the mode of a channel. This + * may require the bot to have operator status on the channel. + * For example, if the bot has operator status, we can grant + * operator status to "Dave" on the #cs channel + * by calling setMode("#cs", "+o Dave"); + * An alternative way of doing this would be to use the op method. + * + * @param channel The channel on which to perform the mode change. + * @param mode The new mode to apply to the channel. This may include + * zero or more arguments if necessary. + * + * @see #op(String,String) op + */ + public final void setMode(String channel, String mode) { + this.sendRawLine("MODE " + channel + " " + mode); + } + + + /** + * Sends an invitation to join a channel. Some channels can be marked + * as "invite-only", so it may be useful to allow a bot to invite people + * into it. + * + * @param nick The nick of the user to invite + * @param channel The channel you are inviting the user to join. + * + */ + public final void sendInvite(String nick, String channel) { + this.sendRawLine("INVITE " + nick + " :" + channel); + } + + + /** + * Bans a user from a channel. An example of a valid hostmask is + * "*!*compu@*.18hp.net". This may be used in conjunction with the + * kick method to permanently remove a user from a channel. + * Successful use of this method may require the bot to have operator + * status itself. + * + * @param channel The channel to ban the user from. + * @param hostmask A hostmask representing the user we're banning. + */ + public final void ban(String channel, String hostmask) { + this.sendRawLine("MODE " + channel + " +b " + hostmask); + } + + + /** + * Unbans a user from a channel. An example of a valid hostmask is + * "*!*compu@*.18hp.net". + * Successful use of this method may require the bot to have operator + * status itself. + * + * @param channel The channel to unban the user from. + * @param hostmask A hostmask representing the user we're unbanning. + */ + public final void unBan(String channel, String hostmask) { + this.sendRawLine("MODE " + channel + " -b " + hostmask); + } + + + /** + * Grants operator privilidges to a user on a channel. + * Successful use of this method may require the bot to have operator + * status itself. + * + * @param channel The channel we're opping the user on. + * @param nick The nick of the user we are opping. + */ + public final void op(String channel, String nick) { + this.setMode(channel, "+o " + nick); + } + + + /** + * Removes operator privilidges from a user on a channel. + * Successful use of this method may require the bot to have operator + * status itself. + * + * @param channel The channel we're deopping the user on. + * @param nick The nick of the user we are deopping. + */ + public final void deOp(String channel, String nick) { + this.setMode(channel, "-o " + nick); + } + + + /** + * Grants voice privilidges to a user on a channel. + * Successful use of this method may require the bot to have operator + * status itself. + * + * @param channel The channel we're voicing the user on. + * @param nick The nick of the user we are voicing. + */ + public final void voice(String channel, String nick) { + this.setMode(channel, "+v " + nick); + } + + + /** + * Removes voice privilidges from a user on a channel. + * Successful use of this method may require the bot to have operator + * status itself. + * + * @param channel The channel we're devoicing the user on. + * @param nick The nick of the user we are devoicing. + */ + public final void deVoice(String channel, String nick) { + this.setMode(channel, "-v " + nick); + } + + + /** + * Set the topic for a channel. + * This method attempts to set the topic of a channel. This + * may require the bot to have operator status if the topic + * is protected. + * + * @param channel The channel on which to perform the mode change. + * @param topic The new topic for the channel. + * + */ + public final void setTopic(String channel, String topic) { + this.sendRawLine("TOPIC " + channel + " :" + topic); + } + + + /** + * Kicks a user from a channel. + * This method attempts to kick a user from a channel and + * may require the bot to have operator status in the channel. + * + * @param channel The channel to kick the user from. + * @param nick The nick of the user to kick. + */ + public final void kick(String channel, String nick) { + this.kick(channel, nick, ""); + } + + + /** + * Kicks a user from a channel, giving a reason. + * This method attempts to kick a user from a channel and + * may require the bot to have operator status in the channel. + * + * @param channel The channel to kick the user from. + * @param nick The nick of the user to kick. + * @param reason A description of the reason for kicking a user. + */ + public final void kick(String channel, String nick, String reason) { + this.sendRawLine("KICK " + channel + " " + nick + " :" + reason); + } + + + /** + * Issues a request for a list of all channels on the IRC server. + * When the PircBot receives information for each channel, it will + * call the onChannelInfo method, which you will need to override + * if you want it to do anything useful. + * + * @see #onChannelInfo(String,int,String) onChannelInfo + */ + public final void listChannels() { + this.listChannels(null); + } + + + /** + * Issues a request for a list of all channels on the IRC server. + * When the PircBot receives information for each channel, it will + * call the onChannelInfo method, which you will need to override + * if you want it to do anything useful. + *

+ * Some IRC servers support certain parameters for LIST requests. + * One example is a parameter of ">10" to list only those channels + * that have more than 10 users in them. Whether these parameters + * are supported or not will depend on the IRC server software. + * + * @param parameters The parameters to supply when requesting the + * list. + * + * @see #onChannelInfo(String,int,String) onChannelInfo + */ + public final void listChannels(String parameters) { + if (parameters == null) { + this.sendRawLine("LIST"); + } + else { + this.sendRawLine("LIST " + parameters); + } + } + + /** + * Adds a line to the log. This log is currently output to the standard + * output and is in the correct format for use by tools such as pisg, the + * Perl IRC Statistics Generator. You may override this method if you wish + * to do something else with log entries. + * Each line in the log begins with a number which + * represents the logging time (as the number of milliseconds since the + * epoch). This timestamp and the following log entry are separated by + * a single space character, " ". Outgoing messages are distinguishable + * by a log entry that has ">>>" immediately following the space character + * after the timestamp. DCC events use "+++" and warnings about unhandled + * Exceptions and Errors use "###". + *

+ * This implementation of the method will only cause log entries to be + * output if the PircBot has had its verbose mode turned on by calling + * setVerbose(true); + * + * @param line The line to add to the log. + */ + public void log(String line) { + if (_verbose) { + System.out.println(System.currentTimeMillis() + " " + line); + } + } + + + /** + * This method handles events when any line of text arrives from the server, + * then calling the appropriate method in the PircBot. This method is + * protected and only called by the InputThread for this instance. + *

+ * This method may not be overridden! + * + * @param line The raw line of text from the server. + */ + protected void handleLine(String line) { + this.log(line); + + // Check for server pings. + if (line.startsWith("PING ")) { + // Respond to the ping and return immediately. + this.onServerPing(line.substring(5)); + return; + } + + String sourceNick = ""; + String sourceLogin = ""; + String sourceHostname = ""; + + StringTokenizer tokenizer = new StringTokenizer(line); + String senderInfo = tokenizer.nextToken(); + String command = tokenizer.nextToken(); + String target = null; + + int exclamation = senderInfo.indexOf("!"); + int at = senderInfo.indexOf("@"); + if (senderInfo.startsWith(":")) { + if (exclamation > 0 && at > 0 && exclamation < at) { + sourceNick = senderInfo.substring(1, exclamation); + sourceLogin = senderInfo.substring(exclamation + 1, at); + sourceHostname = senderInfo.substring(at + 1); + } + else { + + if (tokenizer.hasMoreTokens()) { + String token = command; + + int code = -1; + try { + code = Integer.parseInt(token); + } + catch (NumberFormatException e) { + // Keep the existing value. + } + + if (code != -1) { + String errorStr = token; + String response = line.substring(line.indexOf(errorStr, senderInfo.length()) + 4, line.length()); + this.processServerResponse(code, response); + // Return from the method. + return; + } + else { + // This is not a server response. + // It must be a nick without login and hostname. + // (or maybe a NOTICE or suchlike from the server) + sourceNick = senderInfo; + target = token; + } + } + else { + // We don't know what this line means. + this.onUnknown(line); + // Return from the method; + return; + } + + } + } + + command = command.toUpperCase(); + if (sourceNick.startsWith(":")) { + sourceNick = sourceNick.substring(1); + } + if (target == null) { + target = tokenizer.nextToken(); + } + if (target.startsWith(":")) { + target = target.substring(1); + } + + // Check for CTCP requests. + if (command.equals("PRIVMSG") && line.indexOf(":\u0001") > 0 && line.endsWith("\u0001")) { + String request = line.substring(line.indexOf(":\u0001") + 2, line.length() - 1); + if (request.equals("VERSION")) { + // VERSION request + this.onVersion(sourceNick, sourceLogin, sourceHostname, target); + } + else if (request.startsWith("ACTION ")) { + // ACTION request + this.onAction(sourceNick, sourceLogin, sourceHostname, target, request.substring(7)); + } + else if (request.startsWith("PING ")) { + // PING request + this.onPing(sourceNick, sourceLogin, sourceHostname, target, request.substring(5)); + } + else if (request.equals("TIME")) { + // TIME request + this.onTime(sourceNick, sourceLogin, sourceHostname, target); + } + else if (request.equals("FINGER")) { + // FINGER request + this.onFinger(sourceNick, sourceLogin, sourceHostname, target); + } + else { + // An unknown CTCP message - ignore it. + this.onUnknown(line); + } + } + else if (command.equals("PRIVMSG") && _channelPrefixes.indexOf(target.charAt(0)) >= 0) { + // This is a normal message to a channel. + this.onMessage(target, sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2)); + } + else if (command.equals("PRIVMSG")) { + // This is a private message to us. + this.onPrivateMessage(sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2)); + } + else if (command.equals("JOIN")) { + // Someone is joining a channel. + String channel = target; + this.addUser(channel, new User("", sourceNick)); + this.onJoin(channel, sourceNick, sourceLogin, sourceHostname); + } + else if (command.equals("PART")) { + // Someone is parting from a channel. + this.removeUser(target, sourceNick); + if (sourceNick.equals(this.getNick())) { + this.removeChannel(target); + } + this.onPart(target, sourceNick, sourceLogin, sourceHostname); + } + else if (command.equals("NICK")) { + // Somebody is changing their nick. + String newNick = target; + this.renameUser(sourceNick, newNick); + if (sourceNick.equals(this.getNick())) { + // Update our nick if it was us that changed nick. + this.setNick(newNick); + } + this.onNickChange(sourceNick, sourceLogin, sourceHostname, newNick); + } + else if (command.equals("NOTICE")) { + // Someone is sending a notice. + this.onNotice(sourceNick, sourceLogin, sourceHostname, target, line.substring(line.indexOf(" :") + 2)); + } + else if (command.equals("QUIT")) { + // Someone has quit from the IRC server. + if (sourceNick.equals(this.getNick())) { + this.removeAllChannels(); + } + else { + this.removeUser(sourceNick); + } + this.onQuit(sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2)); + } + else if (command.equals("KICK")) { + // Somebody has been kicked from a channel. + String recipient = tokenizer.nextToken(); + if (recipient.equals(this.getNick())) { + this.removeChannel(target); + } + this.removeUser(target, recipient); + this.onKick(target, sourceNick, sourceLogin, sourceHostname, recipient, line.substring(line.indexOf(" :") + 2)); + } + else if (command.equals("MODE")) { + // Somebody is changing the mode on a channel or user. + String mode = line.substring(line.indexOf(target, 2) + target.length() + 1); + if (mode.startsWith(":")) { + mode = mode.substring(1); + } + this.processMode(target, sourceNick, sourceLogin, sourceHostname, mode); + } + else if (command.equals("TOPIC")) { + // Someone is changing the topic. + this.onTopic(target, line.substring(line.indexOf(" :") + 2), sourceNick, System.currentTimeMillis(), true); + } + else if (command.equals("INVITE")) { + // Somebody is inviting somebody else into a channel. + this.onInvite(target, sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2)); + } + else { + // If we reach this point, then we've found something that the PircBot + // Doesn't currently deal with. + this.onUnknown(line); + } + + } + + + /** + * This method is called once the PircBot has successfully connected to + * the IRC server. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.6 + */ + protected void onConnect() {} + + + /** + * This method carries out the actions to be performed when the PircBot + * gets disconnected. This may happen if the PircBot quits from the + * server, or if the connection is unexpectedly lost. + *

+ * Disconnection from the IRC server is detected immediately if either + * we or the server close the connection normally. If the connection to + * the server is lost, but neither we nor the server have explicitly closed + * the connection, then it may take a few minutes to detect (this is + * commonly referred to as a "ping timeout"). + *

+ * If you wish to get your IRC bot to automatically rejoin a server after + * the connection has been lost, then this is probably the ideal method to + * override to implement such functionality. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + */ + protected void onDisconnect() {} + + + /** + * This method is called by the PircBot when a numeric response + * is received from the IRC server. We use this method to + * allow PircBot to process various responses from the server + * before then passing them on to the onServerResponse method. + *

+ * Note that this method is private and should not appear in any + * of the javadoc generated documenation. + * + * @param code The three-digit numerical code for the response. + * @param response The full response from the IRC server. + */ + private final void processServerResponse(int code, String response) { + + if (code == RPL_LIST) { + // This is a bit of information about a channel. + int firstSpace = response.indexOf(' '); + int secondSpace = response.indexOf(' ', firstSpace + 1); + int thirdSpace = response.indexOf(' ', secondSpace + 1); + int colon = response.indexOf(':'); + String channel = response.substring(firstSpace + 1, secondSpace); + int userCount = 0; + try { + userCount = Integer.parseInt(response.substring(secondSpace + 1, thirdSpace)); + } + catch (NumberFormatException e) { + // Stick with the value of zero. + } + String topic = response.substring(colon + 1); + this.onChannelInfo(channel, userCount, topic); + } + else if (code == RPL_TOPIC) { + // This is topic information about a channel we've just joined. + int firstSpace = response.indexOf(' '); + int secondSpace = response.indexOf(' ', firstSpace + 1); + int colon = response.indexOf(':'); + String channel = response.substring(firstSpace + 1, secondSpace); + String topic = response.substring(colon + 1); + + _topics.put(channel, topic); + + // For backwards compatibility only - this onTopic method is deprecated. + this.onTopic(channel, topic); + } + else if (code == RPL_TOPICINFO) { + StringTokenizer tokenizer = new StringTokenizer(response); + tokenizer.nextToken(); + String channel = tokenizer.nextToken(); + String setBy = tokenizer.nextToken(); + long date = 0; + try { + date = Long.parseLong(tokenizer.nextToken()) * 1000; + } + catch (NumberFormatException e) { + // Stick with the default value of zero. + } + + String topic = (String) _topics.get(channel); + _topics.remove(channel); + + this.onTopic(channel, topic, setBy, date, false); + } + else if (code == RPL_NAMREPLY) { + // This is a list of nicks in a channel that we've just joined. + int channelEndIndex = response.indexOf(" :"); + String channel = response.substring(response.lastIndexOf(' ', channelEndIndex - 1) + 1, channelEndIndex); + + StringTokenizer tokenizer = new StringTokenizer(response.substring(response.indexOf(" :") + 2)); + while (tokenizer.hasMoreTokens()) { + String nick = tokenizer.nextToken(); + String prefix = ""; + if (nick.startsWith("@")) { + // User is an operator in this channel. + prefix = "@"; + } + else if (nick.startsWith("+")) { + // User is voiced in this channel. + prefix = "+"; + } + else if (nick.startsWith(".")) { + // Some wibbly status I've never seen before... + prefix = "."; + } + nick = nick.substring(prefix.length()); + this.addUser(channel, new User(prefix, nick)); + } + } + else if (code == RPL_ENDOFNAMES) { + // This is the end of a NAMES list, so we know that we've got + // the full list of users in the channel that we just joined. + String channel = response.substring(response.indexOf(' ') + 1, response.indexOf(" :")); + User[] users = this.getUsers(channel); + this.onUserList(channel, users); + } + + this.onServerResponse(code, response); + } + + + /** + * This method is called when we receive a numeric response from the + * IRC server. + *

+ * Numerics in the range from 001 to 099 are used for client-server + * connections only and should never travel between servers. Replies + * generated in response to commands are found in the range from 200 + * to 399. Error replies are found in the range from 400 to 599. + *

+ * For example, we can use this method to discover the topic of a + * channel when we join it. If we join the channel #test which + * has a topic of "I am King of Test" then the response + * will be "PircBot #test :I Am King of Test" + * with a code of 332 to signify that this is a topic. + * (This is just an example - note that overriding the + * onTopic method is an easier way of finding the + * topic for a channel). Check the IRC RFC for the full list of other + * command response codes. + *

+ * PircBot implements the interface ReplyConstants, which contains + * contstants that you may find useful here. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param code The three-digit numerical code for the response. + * @param response The full response from the IRC server. + * + * @see ReplyConstants + */ + protected void onServerResponse(int code, String response) {} + + + /** + * This method is called when we receive a user list from the server + * after joining a channel. + *

+ * Shortly after joining a channel, the IRC server sends a list of all + * users in that channel. The PircBot collects this information and + * calls this method as soon as it has the full list. + *

+ * To obtain the nick of each user in the channel, call the getNick() + * method on each User object in the array. + *

+ * At a later time, you may call the getUsers method to obtain an + * up to date list of the users in the channel. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 1.0.0 + * + * @param channel The name of the channel. + * @param users An array of User objects belonging to this channel. + * + * @see User + */ + protected void onUserList(String channel, User[] users) {} + + + /** + * This method is called whenever a message is sent to a channel. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param channel The channel to which the message was sent. + * @param sender The nick of the person who sent the message. + * @param login The login of the person who sent the message. + * @param hostname The hostname of the person who sent the message. + * @param message The actual message sent to the channel. + */ + protected void onMessage(String channel, String sender, String login, String hostname, String message) {} + + + /** + * This method is called whenever a private message is sent to the PircBot. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param sender The nick of the person who sent the private message. + * @param login The login of the person who sent the private message. + * @param hostname The hostname of the person who sent the private message. + * @param message The actual message. + */ + protected void onPrivateMessage(String sender, String login, String hostname, String message) {} + + + /** + * This method is called whenever an ACTION is sent from a user. E.g. + * such events generated by typing "/me goes shopping" in most IRC clients. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param sender The nick of the user that sent the action. + * @param login The login of the user that sent the action. + * @param hostname The hostname of the user that sent the action. + * @param target The target of the action, be it a channel or our nick. + * @param action The action carried out by the user. + */ + protected void onAction(String sender, String login, String hostname, String target, String action) {} + + + /** + * This method is called whenever we receive a notice. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param sourceNick The nick of the user that sent the notice. + * @param sourceLogin The login of the user that sent the notice. + * @param sourceHostname The hostname of the user that sent the notice. + * @param target The target of the notice, be it our nick or a channel name. + * @param notice The notice message. + */ + protected void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice) {} + + + /** + * This method is called whenever someone (possibly us) joins a channel + * which we are on. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param channel The channel which somebody joined. + * @param sender The nick of the user who joined the channel. + * @param login The login of the user who joined the channel. + * @param hostname The hostname of the user who joined the channel. + */ + protected void onJoin(String channel, String sender, String login, String hostname) {} + + + /** + * This method is called whenever someone (possibly us) parts a channel + * which we are on. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param channel The channel which somebody parted from. + * @param sender The nick of the user who parted from the channel. + * @param login The login of the user who parted from the channel. + * @param hostname The hostname of the user who parted from the channel. + */ + protected void onPart(String channel, String sender, String login, String hostname) {} + + + /** + * This method is called whenever someone (possibly us) changes nick on any + * of the channels that we are on. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param oldNick The old nick. + * @param login The login of the user. + * @param hostname The hostname of the user. + * @param newNick The new nick. + */ + protected void onNickChange(String oldNick, String login, String hostname, String newNick) {} + + + /** + * This method is called whenever someone (possibly us) is kicked from + * any of the channels that we are in. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param channel The channel from which the recipient was kicked. + * @param kickerNick The nick of the user who performed the kick. + * @param kickerLogin The login of the user who performed the kick. + * @param kickerHostname The hostname of the user who performed the kick. + * @param recipientNick The unfortunate recipient of the kick. + * @param reason The reason given by the user who performed the kick. + */ + protected void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) {} + + + /** + * This method is called whenever someone (possibly us) quits from the + * server. We will only observe this if the user was in one of the + * channels to which we are connected. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param sourceNick The nick of the user that quit from the server. + * @param sourceLogin The login of the user that quit from the server. + * @param sourceHostname The hostname of the user that quit from the server. + * @param reason The reason given for quitting the server. + */ + protected void onQuit(String sourceNick, String sourceLogin, String sourceHostname, String reason) {} + + + /** + * This method is called whenever a user sets the topic, or when + * PircBot joins a new channel and discovers its topic. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param channel The channel that the topic belongs to. + * @param topic The topic for the channel. + * + * @deprecated As of 1.2.0, replaced by {@link #onTopic(String,String,String,long,boolean)} + */ + protected void onTopic(String channel, String topic) {} + + + /** + * This method is called whenever a user sets the topic, or when + * PircBot joins a new channel and discovers its topic. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param channel The channel that the topic belongs to. + * @param topic The topic for the channel. + * @param setBy The nick of the user that set the topic. + * @param date When the topic was set (milliseconds since the epoch). + * @param changed True if the topic has just been changed, false if + * the topic was already there. + * + */ + protected void onTopic(String channel, String topic, String setBy, long date, boolean changed) {} + + + /** + * After calling the listChannels() method in PircBot, the server + * will start to send us information about each channel on the + * server. You may override this method in order to receive the + * information about each channel as soon as it is received. + *

+ * Note that certain channels, such as those marked as hidden, + * may not appear in channel listings. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param channel The name of the channel. + * @param userCount The number of users visible in this channel. + * @param topic The topic for this channel. + * + * @see #listChannels() listChannels + */ + protected void onChannelInfo(String channel, int userCount, String topic) {} + + + /** + * Called when the mode of a channel is set. We process this in + * order to call the appropriate onOp, onDeop, etc method before + * finally calling the override-able onMode method. + *

+ * Note that this method is private and is not intended to appear + * in the javadoc generated documentation. + * + * @param target The channel or nick that the mode operation applies to. + * @param sourceNick The nick of the user that set the mode. + * @param sourceLogin The login of the user that set the mode. + * @param sourceHostname The hostname of the user that set the mode. + * @param mode The mode that has been set. + */ + private final void processMode(String target, String sourceNick, String sourceLogin, String sourceHostname, String mode) { + + if (_channelPrefixes.indexOf(target.charAt(0)) >= 0) { + // The mode of a channel is being changed. + String channel = target; + StringTokenizer tok = new StringTokenizer(mode); + String[] params = new String[tok.countTokens()]; + + int t = 0; + while (tok.hasMoreTokens()) { + params[t] = tok.nextToken(); + t++; + } + + char pn = ' '; + int p = 1; + + // All of this is very large and ugly, but it's the only way of providing + // what the users want :-/ + for (int i = 0; i < params[0].length(); i++) { + char atPos = params[0].charAt(i); + + if (atPos == '+' || atPos == '-') { + pn = atPos; + } + else if (atPos == 'o') { + if (pn == '+') { + this.updateUser(channel, OP_ADD, params[p]); + onOp(channel, sourceNick, sourceLogin, sourceHostname, params[p]); + } + else { + this.updateUser(channel, OP_REMOVE, params[p]); + onDeop(channel, sourceNick, sourceLogin, sourceHostname, params[p]); + } + p++; + } + else if (atPos == 'v') { + if (pn == '+') { + this.updateUser(channel, VOICE_ADD, params[p]); + onVoice(channel, sourceNick, sourceLogin, sourceHostname, params[p]); + } + else { + this.updateUser(channel, VOICE_REMOVE, params[p]); + onDeVoice(channel, sourceNick, sourceLogin, sourceHostname, params[p]); + } + p++; + } + else if (atPos == 'k') { + if (pn == '+') { + onSetChannelKey(channel, sourceNick, sourceLogin, sourceHostname, params[p]); + } + else { + onRemoveChannelKey(channel, sourceNick, sourceLogin, sourceHostname, params[p]); + } + p++; + } + else if (atPos == 'l') { + if (pn == '+') { + onSetChannelLimit(channel, sourceNick, sourceLogin, sourceHostname, Integer.parseInt(params[p])); + p++; + } + else { + onRemoveChannelLimit(channel, sourceNick, sourceLogin, sourceHostname); + } + } + else if (atPos == 'b') { + if (pn == '+') { + onSetChannelBan(channel, sourceNick, sourceLogin, sourceHostname,params[p]); + } + else { + onRemoveChannelBan(channel, sourceNick, sourceLogin, sourceHostname, params[p]); + } + p++; + } + else if (atPos == 't') { + if (pn == '+') { + onSetTopicProtection(channel, sourceNick, sourceLogin, sourceHostname); + } + else { + onRemoveTopicProtection(channel, sourceNick, sourceLogin, sourceHostname); + } + } + else if (atPos == 'n') { + if (pn == '+') { + onSetNoExternalMessages(channel, sourceNick, sourceLogin, sourceHostname); + } + else { + onRemoveNoExternalMessages(channel, sourceNick, sourceLogin, sourceHostname); + } + } + else if (atPos == 'i') { + if (pn == '+') { + onSetInviteOnly(channel, sourceNick, sourceLogin, sourceHostname); + } + else { + onRemoveInviteOnly(channel, sourceNick, sourceLogin, sourceHostname); + } + } + else if (atPos == 'm') { + if (pn == '+') { + onSetModerated(channel, sourceNick, sourceLogin, sourceHostname); + } + else { + onRemoveModerated(channel, sourceNick, sourceLogin, sourceHostname); + } + } + else if (atPos == 'p') { + if (pn == '+') { + onSetPrivate(channel, sourceNick, sourceLogin, sourceHostname); + } + else { + onRemovePrivate(channel, sourceNick, sourceLogin, sourceHostname); + } + } + else if (atPos == 's') { + if (pn == '+') { + onSetSecret(channel, sourceNick, sourceLogin, sourceHostname); + } + else { + onRemoveSecret(channel, sourceNick, sourceLogin, sourceHostname); + } + } + } + + this.onMode(channel, sourceNick, sourceLogin, sourceHostname, mode); + } + else { + // The mode of a user is being changed. + String nick = target; + this.onUserMode(nick, sourceNick, sourceLogin, sourceHostname, mode); + } + } + + + /** + * Called when the mode of a channel is set. + *

+ * You may find it more convenient to decode the meaning of the mode + * string by overriding the onOp, onDeOp, onVoice, onDeVoice, + * onChannelKey, onDeChannelKey, onChannelLimit, onDeChannelLimit, + * onChannelBan or onDeChannelBan methods as appropriate. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param channel The channel that the mode operation applies to. + * @param sourceNick The nick of the user that set the mode. + * @param sourceLogin The login of the user that set the mode. + * @param sourceHostname The hostname of the user that set the mode. + * @param mode The mode that has been set. + * + */ + protected void onMode(String channel, String sourceNick, String sourceLogin, String sourceHostname, String mode) {} + + + /** + * Called when the mode of a user is set. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 1.2.0 + * + * @param targetNick The nick that the mode operation applies to. + * @param sourceNick The nick of the user that set the mode. + * @param sourceLogin The login of the user that set the mode. + * @param sourceHostname The hostname of the user that set the mode. + * @param mode The mode that has been set. + * + */ + protected void onUserMode(String targetNick, String sourceNick, String sourceLogin, String sourceHostname, String mode) {} + + + + /** + * Called when a user (possibly us) gets granted operator status for a channel. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param recipient The nick of the user that got 'opped'. + */ + protected void onOp(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {} + + + /** + * Called when a user (possibly us) gets operator status taken away. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param recipient The nick of the user that got 'deopped'. + */ + protected void onDeop(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {} + + + /** + * Called when a user (possibly us) gets voice status granted in a channel. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param recipient The nick of the user that got 'voiced'. + */ + protected void onVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {} + + + /** + * Called when a user (possibly us) gets voice status removed. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param recipient The nick of the user that got 'devoiced'. + */ + protected void onDeVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {} + + + /** + * Called when a channel key is set. When the channel key has been set, + * other users may only join that channel if they know the key. Channel keys + * are sometimes referred to as passwords. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param key The new key for the channel. + */ + protected void onSetChannelKey(String channel, String sourceNick, String sourceLogin, String sourceHostname, String key) {} + + + /** + * Called when a channel key is removed. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param key The key that was in use before the channel key was removed. + */ + protected void onRemoveChannelKey(String channel, String sourceNick, String sourceLogin, String sourceHostname, String key) {} + + + /** + * Called when a user limit is set for a channel. The number of users in + * the channel cannot exceed this limit. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param limit The maximum number of users that may be in this channel at the same time. + */ + protected void onSetChannelLimit(String channel, String sourceNick, String sourceLogin, String sourceHostname, int limit) {} + + + /** + * Called when the user limit is removed for a channel. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onRemoveChannelLimit(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a user (possibly us) gets banned from a channel. Being + * banned from a channel prevents any user with a matching hostmask from + * joining the channel. For this reason, most bans are usually directly + * followed by the user being kicked :-) + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param hostmask The hostmask of the user that has been banned. + */ + protected void onSetChannelBan(String channel, String sourceNick, String sourceLogin, String sourceHostname, String hostmask) {} + + + /** + * Called when a hostmask ban is removed from a channel. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + * @param hostmask + */ + protected void onRemoveChannelBan(String channel, String sourceNick, String sourceLogin, String sourceHostname, String hostmask) {} + + + /** + * Called when topic protection is enabled for a channel. Topic protection + * means that only operators in a channel may change the topic. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onSetTopicProtection(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when topic protection is removed for a channel. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onRemoveTopicProtection(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel is set to only allow messages from users that + * are in the channel. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onSetNoExternalMessages(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel is set to allow messages from any user, even + * if they are not actually in the channel. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onRemoveNoExternalMessages(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel is set to 'invite only' mode. A user may only + * join the channel if they are invited by someone who is already in the + * channel. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onSetInviteOnly(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel has 'invite only' removed. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onRemoveInviteOnly(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel is set to 'moderated' mode. If a channel is + * moderated, then only users who have been 'voiced' or 'opped' may speak + * or change their nicks. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onSetModerated(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel has moderated mode removed. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onRemoveModerated(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel is marked as being in private mode. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onSetPrivate(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel is marked as not being in private mode. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onRemovePrivate(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel is set to be in 'secret' mode. Such channels + * typically do not appear on a server's channel listing. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onSetSecret(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when a channel has 'secret' mode removed. + *

+ * This is a type of mode change and is also passed to the onMode + * method in the PircBot class. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param channel The channel in which the mode change took place. + * @param sourceNick The nick of the user that performed the mode change. + * @param sourceLogin The login of the user that performed the mode change. + * @param sourceHostname The hostname of the user that performed the mode change. + */ + protected void onRemoveSecret(String channel, String sourceNick, String sourceLogin, String sourceHostname) {} + + + /** + * Called when we are invited to a channel by a user. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @since PircBot 0.9.5 + * + * @param targetNick The nick of the user being invited - should be us! + * @param sourceNick The nick of the user that sent the invitation. + * @param sourceLogin The login of the user that sent the invitation. + * @param sourceHostname The hostname of the user that sent the invitation. + * @param channel The channel that we're being invited to. + */ + protected void onInvite(String targetNick, String sourceNick, String sourceLogin, String sourceHostname, String channel) {} + + + /** + * This method used to be called when a DCC SEND request was sent to the PircBot. + * Please use the onIncomingFileTransfer method to receive files, as it + * has better functionality and supports resuming. + * + * @deprecated As of PircBot 1.2.0, use {@link #onIncomingFileTransfer(DccFileTransfer)} + */ + protected void onDccSendRequest(String sourceNick, String sourceLogin, String sourceHostname, String filename, long address, int port, int size) {} + + + /** + * This method used to be called when a DCC CHAT request was sent to the PircBot. + * Please use the onIncomingChatRequest method to accept chats, as it + * has better functionality. + * + * @deprecated As of PircBot 1.2.0, use {@link #onIncomingChatRequest(DccChat)} + */ + protected void onDccChatRequest(String sourceNick, String sourceLogin, String sourceHostname, long address, int port) {} + + + /** + * This method is called whenever we receive a VERSION request. + * This abstract implementation responds with the PircBot's _version string, + * so if you override this method, be sure to either mimic its functionality + * or to call super.onVersion(...); + * + * @param sourceNick The nick of the user that sent the VERSION request. + * @param sourceLogin The login of the user that sent the VERSION request. + * @param sourceHostname The hostname of the user that sent the VERSION request. + * @param target The target of the VERSION request, be it our nick or a channel name. + */ + protected void onVersion(String sourceNick, String sourceLogin, String sourceHostname, String target) { + this.sendRawLine("NOTICE " + sourceNick + " :\u0001VERSION " + _version + "\u0001"); + } + + + /** + * This method is called whenever we receive a PING request from another + * user. + *

+ * This abstract implementation responds correctly, so if you override this + * method, be sure to either mimic its functionality or to call + * super.onPing(...); + * + * @param sourceNick The nick of the user that sent the PING request. + * @param sourceLogin The login of the user that sent the PING request. + * @param sourceHostname The hostname of the user that sent the PING request. + * @param target The target of the PING request, be it our nick or a channel name. + * @param pingValue The value that was supplied as an argument to the PING command. + */ + protected void onPing(String sourceNick, String sourceLogin, String sourceHostname, String target, String pingValue) { + this.sendRawLine("NOTICE " + sourceNick + " :\u0001PING " + pingValue + "\u0001"); + } + + + /** + * The actions to perform when a PING request comes from the server. + *

+ * This sends back a correct response, so if you override this method, + * be sure to either mimic its functionality or to call + * super.onServerPing(response); + * + * @param response The response that should be given back in your PONG. + */ + protected void onServerPing(String response) { + this.sendRawLine("PONG " + response); + } + + + /** + * This method is called whenever we receive a TIME request. + *

+ * This abstract implementation responds correctly, so if you override this + * method, be sure to either mimic its functionality or to call + * super.onTime(...); + * + * @param sourceNick The nick of the user that sent the TIME request. + * @param sourceLogin The login of the user that sent the TIME request. + * @param sourceHostname The hostname of the user that sent the TIME request. + * @param target The target of the TIME request, be it our nick or a channel name. + */ + protected void onTime(String sourceNick, String sourceLogin, String sourceHostname, String target) { + this.sendRawLine("NOTICE " + sourceNick + " :\u0001TIME " + new Date().toString() + "\u0001"); + } + + + /** + * This method is called whenever we receive a FINGER request. + *

+ * This abstract implementation responds correctly, so if you override this + * method, be sure to either mimic its functionality or to call + * super.onFinger(...); + * + * @param sourceNick The nick of the user that sent the FINGER request. + * @param sourceLogin The login of the user that sent the FINGER request. + * @param sourceHostname The hostname of the user that sent the FINGER request. + * @param target The target of the FINGER request, be it our nick or a channel name. + */ + protected void onFinger(String sourceNick, String sourceLogin, String sourceHostname, String target) { + this.sendRawLine("NOTICE " + sourceNick + " :\u0001FINGER " + _finger + "\u0001"); + } + + + /** + * This method is called whenever we receive a line from the server that + * the PircBot has not been programmed to recognise. + *

+ * The implementation of this method in the PircBot abstract class + * performs no actions and may be overridden as required. + * + * @param line The raw line that was received from the server. + */ + protected void onUnknown(String line) { + // And then there were none :) + } + + + /** + * Sets the verbose mode. If verbose mode is set to true, then log entries + * will be printed to the standard output. The default value is false and + * will result in no output. For general development, we strongly recommend + * setting the verbose mode to true. + * + * @param verbose true if verbose mode is to be used. Default is false. + */ + public final void setVerbose(boolean verbose) { + _verbose = verbose; + } + + + /** + * Sets the name of the bot, which will be used as its nick when it + * tries to join an IRC server. This should be set before joining + * any servers, otherwise the default nick will be used. You would + * typically call this method from the constructor of the class that + * extends PircBot. + *

+ * The changeNick method should be used if you wish to change your nick + * when you are connected to a server. + * + * @param name The new name of the Bot. + */ + protected final void setName(String name) { + _name = name; + } + + + /** + * Sets the internal nick of the bot. This is only to be called by the + * PircBot class in response to notification of nick changes that apply + * to us. + * + * @param nick The new nick. + */ + private final void setNick(String nick) { + _nick = nick; + } + + + /** + * Sets the internal login of the Bot. This should be set before joining + * any servers. + * + * @param login The new login of the Bot. + */ + protected final void setLogin(String login) { + _login = login; + } + + + /** + * Sets the internal version of the Bot. This should be set before joining + * any servers. + * + * @param version The new version of the Bot. + */ + protected final void setVersion(String version) { + _version = version; + } + + + /** + * Sets the interal finger message. This should be set before joining + * any servers. + * + * @param finger The new finger message for the Bot. + */ + protected final void setFinger(String finger) { + _finger = finger; + } + + + /** + * Gets the name of the PircBot. This is the name that will be used as + * as a nick when we try to join servers. + * + * @return The name of the PircBot. + */ + public final String getName() { + return _name; + } + + + /** + * Returns the current nick of the bot. Note that if you have just changed + * your nick, this method will still return the old nick until confirmation + * of the nick change is received from the server. + *

+ * The nick returned by this method is maintained only by the PircBot + * class and is guaranteed to be correct in the context of the IRC server. + * + * @since PircBot 1.0.0 + * + * @return The current nick of the bot. + */ + public String getNick() { + return _nick; + } + + + /** + * Gets the internal login of the PircBot. + * + * @return The login of the PircBot. + */ + public final String getLogin() { + return _login; + } + + + /** + * Gets the internal version of the PircBot. + * + * @return The version of the PircBot. + */ + public final String getVersion() { + return _version; + } + + + /** + * Gets the internal finger message of the PircBot. + * + * @return The finger message of the PircBot. + */ + public final String getFinger() { + return _finger; + } + + + /** + * Returns whether or not the PircBot is currently connected to a server. + * The result of this method should only act as a rough guide, + * as the result may not be valid by the time you act upon it. + * + * @return True if and only if the PircBot is currently connected to a server. + */ + public final synchronized boolean isConnected() { + return _inputThread != null && _inputThread.isConnected(); + } + + + /** + * Sets the number of milliseconds to delay between consecutive + * messages when there are multiple messages waiting in the + * outgoing message queue. This has a default value of 1000ms. + * It is a good idea to stick to this default value, as it will + * prevent your bot from spamming servers and facing the subsequent + * wrath! However, if you do need to change this delay value (not + * recommended), then this is the method to use. + * + * @param delay The number of milliseconds between each outgoing message. + * + */ + public final void setMessageDelay(long delay) { + if (delay < 0) { + throw new IllegalArgumentException("Cannot have a negative time."); + } + _messageDelay = delay; + } + + + /** + * Returns the number of milliseconds that will be used to separate + * consecutive messages to the server from the outgoing message queue. + * + * @return Number of milliseconds. + */ + public final long getMessageDelay() { + return _messageDelay; + } + + + /** + * Gets the maximum length of any line that is sent via the IRC protocol. + * The IRC RFC specifies that line lengths, including the trailing \r\n + * must not exceed 512 bytes. Hence, there is currently no option to + * change this value in PircBot. All lines greater than this length + * will be truncated before being sent to the IRC server. + * + * @return The maximum line length (currently fixed at 512) + */ + public final int getMaxLineLength() { + return InputThread.MAX_LINE_LENGTH; + } + + + /** + * Gets the number of lines currently waiting in the outgoing message Queue. + * If this returns 0, then the Queue is empty and any new message is likely + * to be sent to the IRC server immediately. + * + * @since PircBot 0.9.9 + * + * @return The number of lines in the outgoing message Queue. + */ + public final int getOutgoingQueueSize() { + return _outQueue.size(); + } + + + /** + * Returns the name of the last IRC server the PircBot tried to connect to. + * This does not imply that the connection attempt to the server was + * successful (we suggest you look at the onConnect method). + * A value of null is returned if the PircBot has never tried to connect + * to a server. + * + * @return The name of the last machine we tried to connect to. Returns + * null if no connection attempts have ever been made. + */ + public final String getServer() { + return _server; + } + + + /** + * Returns the port number of the last IRC server that the PircBot tried + * to connect to. + * This does not imply that the connection attempt to the server was + * successful (we suggest you look at the onConnect method). + * A value of -1 is returned if the PircBot has never tried to connect + * to a server. + * + * @since PircBot 0.9.9 + * + * @return The port number of the last IRC server we connected to. + * Returns -1 if no connection attempts have ever been made. + */ + public final int getPort() { + return _port; + } + + + /** + * Returns the last password that we used when connecting to an IRC server. + * This does not imply that the connection attempt to the server was + * successful (we suggest you look at the onConnect method). + * A value of null is returned if the PircBot has never tried to connect + * to a server using a password. + * + * @since PircBot 0.9.9 + * + * @return The last password that we used when connecting to an IRC server. + * Returns null if we have not previously connected using a password. + */ + public final String getPassword() { + return _password; + } + + + /** + * A convenient method that accepts an IP address represented as a + * long and returns an integer array of size 4 representing the same + * IP address. + * + * @since PircBot 0.9.4 + * + * @param address the long value representing the IP address. + * + * @return An int[] of size 4. + */ + public int[] longToIp(long address) { + int[] ip = new int[4]; + for (int i = 3; i >= 0; i--) { + ip[i] = (int) (address % 256); + address = address / 256; + } + return ip; + } + + + /** + * A convenient method that accepts an IP address represented by a byte[] + * of size 4 and returns this as a long representation of the same IP + * address. + * + * @since PircBot 0.9.4 + * + * @param address the byte[] of size 4 representing the IP address. + * + * @return a long representation of the IP address. + */ + public long ipToLong(byte[] address) { + if (address.length != 4) { + throw new IllegalArgumentException("byte array must be of length 4"); + } + long ipNum = 0; + long multiplier = 1; + for (int i = 3; i >= 0; i--) { + int byteVal = (address[i] + 256) % 256; + ipNum += byteVal*multiplier; + multiplier *= 256; + } + return ipNum; + } + + + /** + * Sets the encoding charset to be used when sending or receiving lines + * from the IRC server. If set to null, then the platform's default + * charset is used. You should only use this method if you are + * trying to send text to an IRC server in a different charset, e.g. + * "GB2312" for Chinese encoding. If a PircBot is currently connected + * to a server, then it must reconnect before this change takes effect. + * + * @since PircBot 1.0.4 + * + * @param charset The new encoding charset to be used by PircBot. + * + * @throws UnsupportedEncodingException If the named charset is not + * supported. + */ + public void setEncoding(String charset) throws UnsupportedEncodingException { + // Just try to see if the charset is supported first... + "".getBytes(charset); + + _charset = charset; + } + + + /** + * Returns the encoding used to send and receive lines from + * the IRC server, or null if not set. Use the setEncoding + * method to change the encoding charset. + * + * @since PircBot 1.0.4 + * + * @return The encoding used to send outgoing messages, or + * null if not set. + */ + public String getEncoding() { + return _charset; + } + + /** + * Returns the InetAddress used by the PircBot. + * This can be used to find the I.P. address from which the PircBot is + * connected to a server. + * + * @since PircBot 1.4.4 + * + * @return The current local InetAddress, or null if never connected. + */ + public InetAddress getInetAddress() { + return _inetAddress; + } + + + /** + * Sets the InetAddress to be used when sending DCC chat or file transfers. + * This can be very useful when you are running a bot on a machine which + * is behind a firewall and you need to tell receiving clients to connect + * to a NAT/router, which then forwards the connection. + * + * @since PircBot 1.4.4 + * + * @param dccInetAddress The new InetAddress, or null to use the default. + */ + public void setDccInetAddress(InetAddress dccInetAddress) { + _dccInetAddress = dccInetAddress; + } + + + /** + * Returns the InetAddress used when sending DCC chat or file transfers. + * If this is null, the default InetAddress will be used. + * + * @since PircBot 1.4.4 + * + * @return The current DCC InetAddress, or null if left as default. + */ + public InetAddress getDccInetAddress() { + return _dccInetAddress; + } + + + /** + * Returns the set of port numbers to be used when sending a DCC chat + * or file transfer. This is useful when you are behind a firewall and + * need to set up port forwarding. The array of port numbers is traversed + * in sequence until a free port is found to listen on. A DCC tranfer will + * fail if all ports are already in use. + * If set to null, any free port number will be used. + * + * @since PircBot 1.4.4 + * + * @return An array of port numbers that PircBot can use to send DCC + * transfers, or null if any port is allowed. + */ + public int[] getDccPorts() { + if (_dccPorts == null || _dccPorts.length == 0) { + return null; + } + // Clone the array to prevent external modification. + return (int[]) _dccPorts.clone(); + } + + + /** + * Sets the choice of port numbers that can be used when sending a DCC chat + * or file transfer. This is useful when you are behind a firewall and + * need to set up port forwarding. The array of port numbers is traversed + * in sequence until a free port is found to listen on. A DCC tranfer will + * fail if all ports are already in use. + * If set to null, any free port number will be used. + * + * @since PircBot 1.4.4 + * + * @param ports The set of port numbers that PircBot may use for DCC + * transfers, or null to let it use any free port (default). + * + */ + public void setDccPorts(int[] ports) { + if (ports == null || ports.length == 0) { + _dccPorts = null; + } + else { + // Clone the array to prevent external modification. + _dccPorts = (int[]) ports.clone(); + } + } + + + /** + * Returns true if and only if the object being compared is the exact + * same instance as this PircBot. This may be useful if you are writing + * a multiple server IRC bot that uses more than one instance of PircBot. + * + * @since PircBot 0.9.9 + * + * @return true if and only if Object o is a PircBot and equal to this. + */ + public boolean equals(Object o) { + // This probably has the same effect as Object.equals, but that may change... + if (o instanceof PircBot) { + PircBot other = (PircBot) o; + return other == this; + } + return false; + } + + + /** + * Returns the hashCode of this PircBot. This method can be called by hashed + * collection classes and is useful for managing multiple instances of + * PircBots in such collections. + * + * @since PircBot 0.9.9 + * + * @return the hash code for this instance of PircBot. + */ + public int hashCode() { + return super.hashCode(); + } + + + /** + * Returns a String representation of this object. + * You may find this useful for debugging purposes, particularly + * if you are using more than one PircBot instance to achieve + * multiple server connectivity. The format of + * this String may change between different versions of PircBot + * but is currently something of the form + * + * Version{PircBot x.y.z Java IRC Bot - www.jibble.org} + * Connected{true} + * Server{irc.dal.net} + * Port{6667} + * Password{} + * + * + * @since PircBot 0.9.10 + * + * @return a String representation of this object. + */ + public String toString() { + return "Version{" + _version + "}" + + " Connected{" + isConnected() + "}" + + " Server{" + _server + "}" + + " Port{" + _port + "}" + + " Password{" + _password + "}"; + } + + + /** + * Returns an array of all users in the specified channel. + *

+ * There are some important things to note about this method:- + *

    + *
  • This method may not return a full list of users if you call it + * before the complete nick list has arrived from the IRC server. + *
  • + *
  • If you wish to find out which users are in a channel as soon + * as you join it, then you should override the onUserList method + * instead of calling this method, as the onUserList method is only + * called as soon as the full user list has been received. + *
  • + *
  • This method will return immediately, as it does not require any + * interaction with the IRC server. + *
  • + *
  • The bot must be in a channel to be able to know which users are + * in it. + *
  • + *
+ * + * @since PircBot 1.0.0 + * + * @param channel The name of the channel to list. + * + * @return An array of User objects. This array is empty if we are not + * in the channel. + * + * @see #onUserList(String,User[]) onUserList + */ + public final User[] getUsers(String channel) { + channel = channel.toLowerCase(); + User[] userArray = new User[0]; + synchronized (_channels) { + Hashtable users = (Hashtable) _channels.get(channel); + if (users != null) { + userArray = new User[users.size()]; + Enumeration enumeration = users.elements(); + for (int i = 0; i < userArray.length; i++) { + User user = (User) enumeration.nextElement(); + userArray[i] = user; + } + } + } + return userArray; + } + + + /** + * Returns an array of all channels that we are in. Note that if you + * call this method immediately after joining a new channel, the new + * channel may not appear in this array as it is not possible to tell + * if the join was successful until a response is received from the + * IRC server. + * + * @since PircBot 1.0.0 + * + * @return A String array containing the names of all channels that we + * are in. + */ + public final String[] getChannels() { + String[] channels = new String[0]; + synchronized (_channels) { + channels = new String[_channels.size()]; + Enumeration enumeration = _channels.keys(); + for (int i = 0; i < channels.length; i++) { + channels[i] = (String) enumeration.nextElement(); + } + } + return channels; + } + + + /** + * Disposes of all thread resources used by this PircBot. This may be + * useful when writing bots or clients that use multiple servers (and + * therefore multiple PircBot instances) or when integrating a PircBot + * with an existing program. + *

+ * Each PircBot runs its own threads for dispatching messages from its + * outgoing message queue and receiving messages from the server. + * Calling dispose() ensures that these threads are + * stopped, thus freeing up system resources and allowing the PircBot + * object to be garbage collected if there are no other references to + * it. + *

+ * Once a PircBot object has been disposed, it should not be used again. + * Attempting to use a PircBot that has been disposed may result in + * unpredictable behaviour. + * + * @since 1.2.2 + */ + public synchronized void dispose() { + //System.out.println("disposing..."); + _outputThread.interrupt(); + _inputThread.dispose(); + } + + + /** + * Add a user to the specified channel in our memory. + * Overwrite the existing entry if it exists. + */ + private final void addUser(String channel, User user) { + channel = channel.toLowerCase(); + synchronized (_channels) { + Hashtable users = (Hashtable) _channels.get(channel); + if (users == null) { + users = new Hashtable(); + _channels.put(channel, users); + } + users.put(user, user); + } + } + + + /** + * Remove a user from the specified channel in our memory. + */ + private final User removeUser(String channel, String nick) { + channel = channel.toLowerCase(); + User user = new User("", nick); + synchronized (_channels) { + Hashtable users = (Hashtable) _channels.get(channel); + if (users != null) { + return (User) users.remove(user); + } + } + return null; + } + + + /** + * Remove a user from all channels in our memory. + */ + private final void removeUser(String nick) { + synchronized (_channels) { + Enumeration enumeration = _channels.keys(); + while (enumeration.hasMoreElements()) { + String channel = (String) enumeration.nextElement(); + this.removeUser(channel, nick); + } + } + } + + + /** + * Rename a user if they appear in any of the channels we know about. + */ + private final void renameUser(String oldNick, String newNick) { + synchronized (_channels) { + Enumeration enumeration = _channels.keys(); + while (enumeration.hasMoreElements()) { + String channel = (String) enumeration.nextElement(); + User user = this.removeUser(channel, oldNick); + if (user != null) { + user = new User(user.getPrefix(), newNick); + this.addUser(channel, user); + } + } + } + } + + + /** + * Removes an entire channel from our memory of users. + */ + private final void removeChannel(String channel) { + channel = channel.toLowerCase(); + synchronized (_channels) { + _channels.remove(channel); + } + } + + + /** + * Removes all channels from our memory of users. + */ + private final void removeAllChannels() { + synchronized(_channels) { + _channels = new Hashtable(); + } + } + + + private final void updateUser(String channel, int userMode, String nick) { + channel = channel.toLowerCase(); + synchronized (_channels) { + Hashtable users = (Hashtable) _channels.get(channel); + User newUser = null; + if (users != null) { + Enumeration enumeration = users.elements(); + while(enumeration.hasMoreElements()) { + User userObj = (User) enumeration.nextElement(); + if (userObj.getNick().equalsIgnoreCase(nick)) { + if (userMode == OP_ADD) { + if (userObj.hasVoice()) { + newUser = new User("@+", nick); + } + else { + newUser = new User("@", nick); + } + } + else if (userMode == OP_REMOVE) { + if(userObj.hasVoice()) { + newUser = new User("+", nick); + } + else { + newUser = new User("", nick); + } + } + else if (userMode == VOICE_ADD) { + if(userObj.isOp()) { + newUser = new User("@+", nick); + } + else { + newUser = new User("+", nick); + } + } + else if (userMode == VOICE_REMOVE) { + if(userObj.isOp()) { + newUser = new User("@", nick); + } + else { + newUser = new User("", nick); + } + } + } + } + } + if (newUser != null) { + users.put(newUser, newUser); + } + else { + // just in case ... + newUser = new User("", nick); + users.put(newUser, newUser); + } + } + } + + + // Connection stuff. + private InputThread _inputThread = null; + private OutputThread _outputThread = null; + private String _charset = null; + private InetAddress _inetAddress = null; + + // Details about the last server that we connected to. + private String _server = null; + private int _port = -1; + private String _password = null; + + // Outgoing message stuff. + private Queue _outQueue = new Queue(); + private long _messageDelay = 1000; + + // A Hashtable of channels that points to a selfreferential Hashtable of + // User objects (used to remember which users are in which channels). + private Hashtable _channels = new Hashtable(); + + // A Hashtable to temporarily store channel topics when we join them + // until we find out who set that topic. + private Hashtable _topics = new Hashtable(); + + private int[] _dccPorts = null; + private InetAddress _dccInetAddress = null; + + // Default settings for the PircBot. + private boolean _autoNickChange = false; + private boolean _verbose = false; + private String _name = "PircBot"; + private String _nick = _name; + private String _login = "PircBot"; + private String _version = "PircBot " + VERSION + " Java IRC Bot - www.jibble.org"; + private String _finger = "You ought to be arrested for fingering a bot!"; + + private String _channelPrefixes = "#&+!"; +} diff --git a/EssentialsUpdate/src/org/jibble/pircbot/Queue.java b/EssentialsUpdate/src/org/jibble/pircbot/Queue.java new file mode 100755 index 000000000..fd8d47781 --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/Queue.java @@ -0,0 +1,146 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + + +package org.jibble.pircbot; + +import java.util.Vector; + +/** + * Queue is a definition of a data structure that may + * act as a queue - that is, data can be added to one end of the + * queue and data can be requested from the head end of the queue. + * This class is thread safe for multiple producers and a single + * consumer. The next() method will block until there is data in + * the queue. + * + * This has now been modified so that it is compatible with + * the earlier JDK1.1 in order to be suitable for running on + * mobile appliances. This means replacing the LinkedList with + * a Vector, which is hardly ideal, but this Queue is typically + * only polled every second before dispatching messages. + * + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public class Queue { + + + /** + * Constructs a Queue object of unlimited size. + */ + public Queue() { + + } + + + /** + * Adds an Object to the end of the Queue. + * + * @param o The Object to be added to the Queue. + */ + public void add(Object o) { + synchronized(_queue) { + _queue.addElement(o); + _queue.notify(); + } + } + + + /** + * Adds an Object to the front of the Queue. + * + * @param o The Object to be added to the Queue. + */ + public void addFront(Object o) { + synchronized(_queue) { + _queue.insertElementAt(o, 0); + _queue.notify(); + } + } + + + /** + * Returns the Object at the front of the Queue. This + * Object is then removed from the Queue. If the Queue + * is empty, then this method shall block until there + * is an Object in the Queue to return. + * + * @return The next item from the front of the queue. + */ + public Object next() { + + Object o = null; + + // Block if the Queue is empty. + synchronized(_queue) { + if (_queue.size() == 0) { + try { + _queue.wait(); + } + catch (InterruptedException e) { + return null; + } + } + + // Return the Object. + try { + o = _queue.firstElement(); + _queue.removeElementAt(0); + } + catch (ArrayIndexOutOfBoundsException e) { + throw new InternalError("Race hazard in Queue object."); + } + } + + return o; + } + + + /** + * Returns true if the Queue is not empty. If another + * Thread empties the Queue before next() is + * called, then the call to next() shall block + * until the Queue has been populated again. + * + * @return True only if the Queue not empty. + */ + public boolean hasNext() { + return (this.size() != 0); + } + + + /** + * Clears the contents of the Queue. + */ + public void clear() { + synchronized(_queue) { + _queue.removeAllElements(); + } + } + + + /** + * Returns the size of the Queue. + * + * @return The current size of the queue. + */ + public int size() { + return _queue.size(); + } + + + private Vector _queue = new Vector(); + +} diff --git a/EssentialsUpdate/src/org/jibble/pircbot/ReplyConstants.java b/EssentialsUpdate/src/org/jibble/pircbot/ReplyConstants.java new file mode 100755 index 000000000..2d8e696d5 --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/ReplyConstants.java @@ -0,0 +1,176 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + + +package org.jibble.pircbot; + +/** + * This interface contains the values of all numeric replies specified + * in section 6 of RFC 1459. Refer to RFC 1459 for further information. + *

+ * If you override the onServerResponse method in the PircBot class, + * you may find these constants useful when comparing the numeric + * value of a given code. + * + * @since 1.0.0 + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public interface ReplyConstants { + + + // Error Replies. + public static final int ERR_NOSUCHNICK = 401; + public static final int ERR_NOSUCHSERVER = 402; + public static final int ERR_NOSUCHCHANNEL = 403; + public static final int ERR_CANNOTSENDTOCHAN = 404; + public static final int ERR_TOOMANYCHANNELS = 405; + public static final int ERR_WASNOSUCHNICK = 406; + public static final int ERR_TOOMANYTARGETS = 407; + public static final int ERR_NOORIGIN = 409; + public static final int ERR_NORECIPIENT = 411; + public static final int ERR_NOTEXTTOSEND = 412; + public static final int ERR_NOTOPLEVEL = 413; + public static final int ERR_WILDTOPLEVEL = 414; + public static final int ERR_UNKNOWNCOMMAND = 421; + public static final int ERR_NOMOTD = 422; + public static final int ERR_NOADMININFO = 423; + public static final int ERR_FILEERROR = 424; + public static final int ERR_NONICKNAMEGIVEN = 431; + public static final int ERR_ERRONEUSNICKNAME = 432; + public static final int ERR_NICKNAMEINUSE = 433; + public static final int ERR_NICKCOLLISION = 436; + public static final int ERR_USERNOTINCHANNEL = 441; + public static final int ERR_NOTONCHANNEL = 442; + public static final int ERR_USERONCHANNEL = 443; + public static final int ERR_NOLOGIN = 444; + public static final int ERR_SUMMONDISABLED = 445; + public static final int ERR_USERSDISABLED = 446; + public static final int ERR_NOTREGISTERED = 451; + public static final int ERR_NEEDMOREPARAMS = 461; + public static final int ERR_ALREADYREGISTRED = 462; + public static final int ERR_NOPERMFORHOST = 463; + public static final int ERR_PASSWDMISMATCH = 464; + public static final int ERR_YOUREBANNEDCREEP = 465; + public static final int ERR_KEYSET = 467; + public static final int ERR_CHANNELISFULL = 471; + public static final int ERR_UNKNOWNMODE = 472; + public static final int ERR_INVITEONLYCHAN = 473; + public static final int ERR_BANNEDFROMCHAN = 474; + public static final int ERR_BADCHANNELKEY = 475; + public static final int ERR_NOPRIVILEGES = 481; + public static final int ERR_CHANOPRIVSNEEDED = 482; + public static final int ERR_CANTKILLSERVER = 483; + public static final int ERR_NOOPERHOST = 491; + public static final int ERR_UMODEUNKNOWNFLAG = 501; + public static final int ERR_USERSDONTMATCH = 502; + + + // Command Responses. + public static final int RPL_TRACELINK = 200; + public static final int RPL_TRACECONNECTING = 201; + public static final int RPL_TRACEHANDSHAKE = 202; + public static final int RPL_TRACEUNKNOWN = 203; + public static final int RPL_TRACEOPERATOR = 204; + public static final int RPL_TRACEUSER = 205; + public static final int RPL_TRACESERVER = 206; + public static final int RPL_TRACENEWTYPE = 208; + public static final int RPL_STATSLINKINFO = 211; + public static final int RPL_STATSCOMMANDS = 212; + public static final int RPL_STATSCLINE = 213; + public static final int RPL_STATSNLINE = 214; + public static final int RPL_STATSILINE = 215; + public static final int RPL_STATSKLINE = 216; + public static final int RPL_STATSYLINE = 218; + public static final int RPL_ENDOFSTATS = 219; + public static final int RPL_UMODEIS = 221; + public static final int RPL_STATSLLINE = 241; + public static final int RPL_STATSUPTIME = 242; + public static final int RPL_STATSOLINE = 243; + public static final int RPL_STATSHLINE = 244; + public static final int RPL_LUSERCLIENT = 251; + public static final int RPL_LUSEROP = 252; + public static final int RPL_LUSERUNKNOWN = 253; + public static final int RPL_LUSERCHANNELS = 254; + public static final int RPL_LUSERME = 255; + public static final int RPL_ADMINME = 256; + public static final int RPL_ADMINLOC1 = 257; + public static final int RPL_ADMINLOC2 = 258; + public static final int RPL_ADMINEMAIL = 259; + public static final int RPL_TRACELOG = 261; + public static final int RPL_NONE = 300; + public static final int RPL_AWAY = 301; + public static final int RPL_USERHOST = 302; + public static final int RPL_ISON = 303; + public static final int RPL_UNAWAY = 305; + public static final int RPL_NOWAWAY = 306; + public static final int RPL_WHOISUSER = 311; + public static final int RPL_WHOISSERVER = 312; + public static final int RPL_WHOISOPERATOR = 313; + public static final int RPL_WHOWASUSER = 314; + public static final int RPL_ENDOFWHO = 315; + public static final int RPL_WHOISIDLE = 317; + public static final int RPL_ENDOFWHOIS = 318; + public static final int RPL_WHOISCHANNELS = 319; + public static final int RPL_LISTSTART = 321; + public static final int RPL_LIST = 322; + public static final int RPL_LISTEND = 323; + public static final int RPL_CHANNELMODEIS = 324; + public static final int RPL_NOTOPIC = 331; + public static final int RPL_TOPIC = 332; + public static final int RPL_TOPICINFO = 333; + public static final int RPL_INVITING = 341; + public static final int RPL_SUMMONING = 342; + public static final int RPL_VERSION = 351; + public static final int RPL_WHOREPLY = 352; + public static final int RPL_NAMREPLY = 353; + public static final int RPL_LINKS = 364; + public static final int RPL_ENDOFLINKS = 365; + public static final int RPL_ENDOFNAMES = 366; + public static final int RPL_BANLIST = 367; + public static final int RPL_ENDOFBANLIST = 368; + public static final int RPL_ENDOFWHOWAS = 369; + public static final int RPL_INFO = 371; + public static final int RPL_MOTD = 372; + public static final int RPL_ENDOFINFO = 374; + public static final int RPL_MOTDSTART = 375; + public static final int RPL_ENDOFMOTD = 376; + public static final int RPL_YOUREOPER = 381; + public static final int RPL_REHASHING = 382; + public static final int RPL_TIME = 391; + public static final int RPL_USERSSTART = 392; + public static final int RPL_USERS = 393; + public static final int RPL_ENDOFUSERS = 394; + public static final int RPL_NOUSERS = 395; + + + // Reserved Numerics. + public static final int RPL_TRACECLASS = 209; + public static final int RPL_STATSQLINE = 217; + public static final int RPL_SERVICEINFO = 231; + public static final int RPL_ENDOFSERVICES = 232; + public static final int RPL_SERVICE = 233; + public static final int RPL_SERVLIST = 234; + public static final int RPL_SERVLISTEND = 235; + public static final int RPL_WHOISCHANOP = 316; + public static final int RPL_KILLDONE = 361; + public static final int RPL_CLOSING = 362; + public static final int RPL_CLOSEEND = 363; + public static final int RPL_INFOSTART = 373; + public static final int RPL_MYPORTIS = 384; + public static final int ERR_YOUWILLBEBANNED = 466; + public static final int ERR_BADCHANMASK = 476; + public static final int ERR_NOSERVICEHOST = 492; + +} diff --git a/EssentialsUpdate/src/org/jibble/pircbot/User.java b/EssentialsUpdate/src/org/jibble/pircbot/User.java new file mode 100755 index 000000000..cb2bfa051 --- /dev/null +++ b/EssentialsUpdate/src/org/jibble/pircbot/User.java @@ -0,0 +1,161 @@ +/* +Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + +package org.jibble.pircbot; + +/** + * This class is used to represent a user on an IRC server. + * Instances of this class are returned by the getUsers method + * in the PircBot class. + *

+ * Note that this class no longer implements the Comparable interface + * for Java 1.1 compatibility reasons. + * + * @since 1.0.0 + * @author Paul James Mutton, + * http://www.jibble.org/ + * @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009) + */ +public class User { + + + /** + * Constructs a User object with a known prefix and nick. + * + * @param prefix The status of the user, for example, "@". + * @param nick The nick of the user. + */ + User(String prefix, String nick) { + _prefix = prefix; + _nick = nick; + _lowerNick = nick.toLowerCase(); + } + + + /** + * Returns the prefix of the user. If the User object has been obtained + * from a list of users in a channel, then this will reflect the user's + * status in that channel. + * + * @return The prefix of the user. If there is no prefix, then an empty + * String is returned. + */ + public String getPrefix() { + return _prefix; + } + + + /** + * Returns whether or not the user represented by this object is an + * operator. If the User object has been obtained from a list of users + * in a channel, then this will reflect the user's operator status in + * that channel. + * + * @return true if the user is an operator in the channel. + */ + public boolean isOp() { + return _prefix.indexOf('@') >= 0; + } + + + /** + * Returns whether or not the user represented by this object has + * voice. If the User object has been obtained from a list of users + * in a channel, then this will reflect the user's voice status in + * that channel. + * + * @return true if the user has voice in the channel. + */ + public boolean hasVoice() { + return _prefix.indexOf('+') >= 0; + } + + + /** + * Returns the nick of the user. + * + * @return The user's nick. + */ + public String getNick() { + return _nick; + } + + + /** + * Returns the nick of the user complete with their prefix if they + * have one, e.g. "@Dave". + * + * @return The user's prefix and nick. + */ + public String toString() { + return this.getPrefix() + this.getNick(); + } + + + /** + * Returns true if the nick represented by this User object is the same + * as the argument. A case insensitive comparison is made. + * + * @return true if the nicks are identical (case insensitive). + */ + public boolean equals(String nick) { + return nick.toLowerCase().equals(_lowerNick); + } + + + /** + * Returns true if the nick represented by this User object is the same + * as the nick of the User object given as an argument. + * A case insensitive comparison is made. + * + * @return true if o is a User object with a matching lowercase nick. + */ + public boolean equals(Object o) { + if (o instanceof User) { + User other = (User) o; + return other._lowerNick.equals(_lowerNick); + } + return false; + } + + + /** + * Returns the hash code of this User object. + * + * @return the hash code of the User object. + */ + public int hashCode() { + return _lowerNick.hashCode(); + } + + + /** + * Returns the result of calling the compareTo method on lowercased + * nicks. This is useful for sorting lists of User objects. + * + * @return the result of calling compareTo on lowercased nicks. + */ + public int compareTo(Object o) { + if (o instanceof User) { + User other = (User) o; + return other._lowerNick.compareTo(_lowerNick); + } + return -1; + } + + + private String _prefix; + private String _nick; + private String _lowerNick; + +} -- cgit v1.2.3 From e628c36172590bc7bbae7eda9855890c1896250e Mon Sep 17 00:00:00 2001 From: snowleo Date: Wed, 12 Oct 2011 12:20:02 +0200 Subject: Cleanup --- .../earth2me/essentials/update/EssentialsHelp.java | 3 +- .../src/com/earth2me/essentials/update/IrcBot.java | 73 +++++++++++++++------- 2 files changed, 51 insertions(+), 25 deletions(-) (limited to 'EssentialsUpdate/src') diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java b/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java index d70d01a01..3caa22cc3 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/EssentialsHelp.java @@ -32,8 +32,9 @@ public class EssentialsHelp extends PlayerListener private final static Charset UTF8 = Charset.forName("utf-8"); private transient IrcBot ircBot; - public EssentialsHelp(Plugin plugin) + public EssentialsHelp(final Plugin plugin) { + super(); this.plugin = plugin; this.server = plugin.getServer(); } diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/IrcBot.java b/EssentialsUpdate/src/com/earth2me/essentials/update/IrcBot.java index ce6205474..a314df15d 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/IrcBot.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/IrcBot.java @@ -1,7 +1,6 @@ package com.earth2me.essentials.update; import java.io.IOException; -import java.util.Enumeration; import java.util.logging.Level; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -13,28 +12,29 @@ import org.jibble.pircbot.User; public class IrcBot extends PircBot { - private static final String channel = "#essentials"; - private static final int port = 6667; - private static final String server = "irc.esper.net"; + private static final String CHANNEL = "#essentials"; + private static final int PORT = 6667; + private static final String SERVER = "irc.esper.net"; private transient boolean reconnect = true; - private transient Player player; + private final transient Player player; private transient boolean kicked = false; - public IrcBot(Player player, final String nickName, final String versionString) + public IrcBot(final Player player, final String nickName, final String versionString) { + super(); this.player = player; setName(nickName); setLogin("esshelp"); setVersion(versionString); connect(); - joinChannel(channel); + joinChannel(CHANNEL); } private void connect() { try { - connect(server, port); + connect(SERVER, PORT); return; } catch (IOException ex) @@ -45,7 +45,6 @@ public class IrcBot extends PircBot { Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); } - } public void quit() @@ -63,10 +62,35 @@ public class IrcBot extends PircBot @Override protected void onDisconnect() { - super.onDisconnect(); if (reconnect) { - connect(); + int tries = 10; + while (!isConnected()) + { + try + { + tries--; + reconnect(); + } + catch (Exception e) + { + Bukkit.getLogger().log(Level.WARNING, e.getMessage(), e); + try + { + Thread.sleep(10000); + } + catch (InterruptedException ex) + { + Bukkit.getLogger().log(Level.WARNING, e.getMessage(), e); + } + } + if (tries <= 0) + { + player.sendMessage("Connection lost to server."); + kicked = true; + break; + } + } } } @@ -110,25 +134,25 @@ public class IrcBot extends PircBot player.sendMessage(formatChatMessage(channel, topic, false)); } - public String formatChatMessage(String nick, String message, boolean action) + public String formatChatMessage(final String nick, final String message, final boolean action) { - final StringBuilder sb = new StringBuilder(); - sb.append("§6"); + final StringBuilder builder = new StringBuilder(); + builder.append("§6"); if (action) { - sb.append('*'); + builder.append('*'); } - sb.append(nick); + builder.append(nick); if (!action) { - sb.append(':'); + builder.append(':'); } - sb.append(" §7"); - sb.append(replaceColors(message)); - return sb.toString(); + builder.append(" §7"); + builder.append(replaceColors(message)); + return builder.toString(); } - private String replaceColors(String message) + private String replaceColors(final String message) { String m = Colors.removeFormatting(message); m = m.replaceAll("\u000310(,(0?[0-9]|1[0-5]))?", "§b"); @@ -147,17 +171,18 @@ public class IrcBot extends PircBot m = m.replaceAll("\u00030?8(,(0?[0-9]|1[0-5]))?", "§e"); m = m.replaceAll("\u00030?9(,(0?[0-9]|1[0-5]))?", "§a"); m = m.replaceAll("\u00030?0(,(0?[0-9]|1[0-5]))?", "§f"); + m = m.replace("\u000f", "§7"); m = Colors.removeColors(m); return m; } - public void sendMessage(String message) + public void sendMessage(final String message) { - sendMessage(channel, message); + sendMessage(CHANNEL, message); } public User[] getUsers() { - return getUsers(channel); + return getUsers(CHANNEL); } } -- cgit v1.2.3