-
Notifications
You must be signed in to change notification settings - Fork 0
/
cmd_chat.rb
173 lines (151 loc) · 4.87 KB
/
cmd_chat.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env ruby
# Copyright notice:
# (C) 2009-2010
# This software is provided 'as-is' without any express or implied warranty.
# In no event will the authors be held liable for damages arising from the
# use of this software. All license is reserved.
$LOAD_PATH.push File.dirname(__FILE__)
require 'client3.rb'
$LOAD_PATH.push FILE_DIRECTORY
# Ruby tool used to grab the source of included files, not just their content
SCRIPT_LINES__ = {}
class Chat3
def initialize
@cmds = []
@controls = []
@var = {}
@connection = ChatConnection.new do |type, sender, room, msg|
if type == MSG_BROADCAST
dispatch :incoming_broadcast, sender, room, msg
remote_chat(sender, room, msg) unless msg.empty?
elsif type == MSG_COMMAND
remote_command(sender, msg)
else
if not type and msg
add_error(msg)
end
end
end
load_command_methods()
dispatch(:startup)
end
def connect(addr, port)
raise "You are not registered!" unless @var[:pub_rsa] and @var[:our_name]
@connection.connect(addr, port.to_i, @var[:pub_rsa], @var[:our_name])
end
def run
$stdin.each_line do |msg|
local_line(msg)
end rescue add_msg("Disconnecting...")
@connection.disconnect
end
def disconnect
@connection.disconnect
end
# We've received a control from the server or from another user
def remote_command(sender, msg)
indx = ((msg =~ /\W/) || msg.length)
cmd = msg[0...indx]
body = msg[indx+1..-1].to_s
@connection.mutex.synchronize do
if @controls.include? cmd
############## dispatch incoming remote control event
begin
self.send("remote_#{cmd}", sender, body)
rescue
add_error("remote command from #{sender} (#{cmd}) failed: #{$!}\n" +
"#{[email protected]("\n")}")
end
else
add_error "received invalid control from #{sender}: '#{cmd}'"
end
end
end
# We've received a chat message
def remote_chat(sender, room, msg)
add_msg "<#{room || 'unknown'}> #{sender}: #{msg}"
end
# We need to dispatch an event
def dispatch(event_type, *params)
@connection.mutex.synchronize do
begin
self.send("event_#{event_type}", *params)
rescue
add_error("Event #{event_type} raised an exception: #{$!}")
end
end
end
# Handle one line of local input
def local_line(msg)
msg.strip!
if msg[0,1] == '/'
msg[0,1] = ''
indx = ((msg =~ /\W/) || msg.length)
cmd = msg[0...indx]
body = msg[indx+1..-1].to_s
@connection.mutex.synchronize do
if @cmds.include? cmd
############## dispatch incoming local control event
begin
self.send("local_#{cmd}", body)
rescue
add_error("local command '#{cmd}' generated an exception: #{$!}\n#{[email protected]("\n")}")
end
else
add_error "invalid local command: '#{cmd}'"
end
end
elsif msg.length > 0
dispatch :outgoing_broadcast, msg
@connection.chat_msg(msg, @var[:room])
end
end
# This method gets invoked if the local user's environment file (env.yml)
# does not contain their username and public/private RSA key pair. This
# method should prompt for a (unique) username, and then generate an RSA
# keypair, and return all three: username, pub_rsa, prv_rsa
def keygen_tool
return nil, nil, nil # ADD CODE HERE
end
# Load methods which can be used for /cmd commands
def load_command_methods()
begin
# Add all the newly-defined methods to our call list
mlist = self.methods # Get the current list of methods
load 'user3.rb' # install the user-defined methods
begin
load 'local.rb' # methods local to the user
rescue LoadError; end
# Load in the included files' code, but only once
unless @var[:script_lines]
@var[:script_lines] = []
SCRIPT_LINES__.each do |k,v|
@var[:script_lines] += v if k.include? 'user3.rb'
end
end
new_methods = self.methods.select { |m| not mlist.include? m }
# Find, translate and add any new user commands
@cmds += new_methods.select { |m| m =~ /^local_/ }
@cmds.collect! { |cmd| cmd.sub 'local_', '' }
# Find and add any new control handlers
@controls += new_methods.select { |m| m =~ /^remote_/ }
@controls.collect! { |cmd| cmd.sub 'remote_', '' }
rescue SyntaxError
add_error "Plugins could not be loaded (#{$!})."
rescue
add_error $!
end
end # of load_command_methods()
# Print a message to the screen. Type is ignored in console mode.
def add_msg(msg, type = nil)
##### local message event
puts msg
$stdout.flush
end
# Print an error to the screen
def add_error(msg)
add_msg "* Error: #{msg}"
end
end # of class Chat3
window = Chat3.new
window.run