globalchat 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # GlobalChat QtRuby
2
+
3
+ Works in 1.8.7 and 1.9.3
4
+
5
+ Not intended for individual distribution
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/ServerList.ui ADDED
@@ -0,0 +1,159 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ui version="4.0">
3
+ <class>Dialog</class>
4
+ <widget class="QDialog" name="Dialog">
5
+ <property name="geometry">
6
+ <rect>
7
+ <x>0</x>
8
+ <y>0</y>
9
+ <width>402</width>
10
+ <height>339</height>
11
+ </rect>
12
+ </property>
13
+ <property name="minimumSize">
14
+ <size>
15
+ <width>400</width>
16
+ <height>339</height>
17
+ </size>
18
+ </property>
19
+ <property name="maximumSize">
20
+ <size>
21
+ <width>402</width>
22
+ <height>339</height>
23
+ </size>
24
+ </property>
25
+ <property name="windowTitle">
26
+ <string>Dialog</string>
27
+ </property>
28
+ <widget class="QListWidget" name="listWidget">
29
+ <property name="geometry">
30
+ <rect>
31
+ <x>0</x>
32
+ <y>0</y>
33
+ <width>401</width>
34
+ <height>141</height>
35
+ </rect>
36
+ </property>
37
+ </widget>
38
+ <widget class="QLabel" name="label">
39
+ <property name="geometry">
40
+ <rect>
41
+ <x>20</x>
42
+ <y>170</y>
43
+ <width>46</width>
44
+ <height>13</height>
45
+ </rect>
46
+ </property>
47
+ <property name="text">
48
+ <string>Handle</string>
49
+ </property>
50
+ </widget>
51
+ <widget class="QLabel" name="label_2">
52
+ <property name="geometry">
53
+ <rect>
54
+ <x>20</x>
55
+ <y>210</y>
56
+ <width>46</width>
57
+ <height>13</height>
58
+ </rect>
59
+ </property>
60
+ <property name="text">
61
+ <string>Host</string>
62
+ </property>
63
+ </widget>
64
+ <widget class="QLabel" name="label_3">
65
+ <property name="geometry">
66
+ <rect>
67
+ <x>210</x>
68
+ <y>210</y>
69
+ <width>46</width>
70
+ <height>13</height>
71
+ </rect>
72
+ </property>
73
+ <property name="text">
74
+ <string>Port</string>
75
+ </property>
76
+ </widget>
77
+ <widget class="QLabel" name="label_4">
78
+ <property name="geometry">
79
+ <rect>
80
+ <x>20</x>
81
+ <y>250</y>
82
+ <width>46</width>
83
+ <height>13</height>
84
+ </rect>
85
+ </property>
86
+ <property name="text">
87
+ <string>Password</string>
88
+ </property>
89
+ </widget>
90
+ <widget class="QLineEdit" name="lineEdit">
91
+ <property name="geometry">
92
+ <rect>
93
+ <x>80</x>
94
+ <y>170</y>
95
+ <width>113</width>
96
+ <height>20</height>
97
+ </rect>
98
+ </property>
99
+ </widget>
100
+ <widget class="QLineEdit" name="lineEdit_2">
101
+ <property name="geometry">
102
+ <rect>
103
+ <x>80</x>
104
+ <y>210</y>
105
+ <width>113</width>
106
+ <height>20</height>
107
+ </rect>
108
+ </property>
109
+ </widget>
110
+ <widget class="QLineEdit" name="lineEdit_3">
111
+ <property name="geometry">
112
+ <rect>
113
+ <x>240</x>
114
+ <y>210</y>
115
+ <width>113</width>
116
+ <height>20</height>
117
+ </rect>
118
+ </property>
119
+ </widget>
120
+ <widget class="QLineEdit" name="lineEdit_4">
121
+ <property name="geometry">
122
+ <rect>
123
+ <x>80</x>
124
+ <y>250</y>
125
+ <width>113</width>
126
+ <height>20</height>
127
+ </rect>
128
+ </property>
129
+ </widget>
130
+ <widget class="QPushButton" name="pushButton">
131
+ <property name="geometry">
132
+ <rect>
133
+ <x>20</x>
134
+ <y>300</y>
135
+ <width>75</width>
136
+ <height>23</height>
137
+ </rect>
138
+ </property>
139
+ <property name="text">
140
+ <string>Refresh</string>
141
+ </property>
142
+ </widget>
143
+ <widget class="QPushButton" name="pushButton_2">
144
+ <property name="geometry">
145
+ <rect>
146
+ <x>120</x>
147
+ <y>300</y>
148
+ <width>75</width>
149
+ <height>23</height>
150
+ </rect>
151
+ </property>
152
+ <property name="text">
153
+ <string>Connect</string>
154
+ </property>
155
+ </widget>
156
+ </widget>
157
+ <resources/>
158
+ <connections/>
159
+ </ui>
data/bin/globalchat ADDED
@@ -0,0 +1,439 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+
6
+ require 'Qt4'
7
+ require 'qtuitools'
8
+ require 'net/http'
9
+ require 'socket'
10
+ require 'thread'
11
+ require 'pstore'
12
+
13
+
14
+ class GlobalChatController < Qt::Object
15
+
16
+ attr_accessor :chat_token,
17
+ :chat_buffer,
18
+ :handles_list,
19
+ :nicks,
20
+ :handle,
21
+ :handle_text_field,
22
+ :connect_button,
23
+ :server_list_window,
24
+ :chat_window,
25
+ :chat_window_text,
26
+ :chat_message,
27
+ :application,
28
+ :scroll_view,
29
+ :last_scroll_view_height,
30
+ :host,
31
+ :port,
32
+ :password,
33
+ :ts,
34
+ :server_name
35
+
36
+ signals :updateChatViews, :updateTitles, :beep
37
+
38
+
39
+ def sendMessage
40
+ begin
41
+ @message = self.chat_message.text
42
+ if @message != ""
43
+ post_message(@message)
44
+ self.chat_message.text = ''
45
+ end
46
+ rescue
47
+ autoreconnect
48
+ end
49
+ end
50
+
51
+ def sign_on
52
+ #log "Connecting to: #{@host} #{@port}"
53
+ begin
54
+ @ts = TCPSocket.open(@host, @port)
55
+ rescue
56
+ log("Could not connect to GlobalChat server. Will retry in 5 seconds.")
57
+ return false
58
+ end
59
+ @last_ping = Time.now # fake ping
60
+ sign_on_array = @password == "" ? [@handle] : [@handle, @password]
61
+ send_message("SIGNON", sign_on_array)
62
+ begin_async_read_queue
63
+ $autoreconnect = true
64
+ true
65
+ end
66
+
67
+ def autoreconnect
68
+ unless $autoreconnect == false
69
+ loop do
70
+ sleep 5
71
+ if sign_on
72
+ break
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ def return_to_server_list
79
+ #@mutex.synchronize do
80
+ alert "GlobalChat connection crashed."
81
+ $gc.hide
82
+ $sl.show
83
+ #end
84
+ end
85
+
86
+ def update_and_scroll
87
+ emit updateChatViews
88
+ end
89
+
90
+ def begin_async_read_queue
91
+ @mutex = Mutex.new
92
+ Thread.new do
93
+ loop do
94
+ #sleep 0.1
95
+ data = ""
96
+ begin
97
+ while line = @ts.recv(1)
98
+ # pongout disconnect reconnect below...
99
+ #raise if @last_ping < Time.now - 120 # opted out
100
+ break if line == "\0"
101
+ data += line
102
+ end
103
+ rescue
104
+ autoreconnect
105
+ break
106
+ end
107
+ data = data.force_encoding("UTF-8")
108
+ parse_line(data)
109
+ end
110
+ end
111
+ end
112
+
113
+ def parse_line(line)
114
+ $stderr.print "#{line}\n"
115
+ parr = line.split("::!!::")
116
+ command = parr.first
117
+ if command == "TOKEN"
118
+ @chat_token = parr[1]
119
+ @handle = parr[2]
120
+ @server_name = parr[3]
121
+ emit updateTitles
122
+ output_to_chat_window "Connected to #{@server_name} \n"
123
+ ping
124
+ get_handles
125
+ $connected = true
126
+ elsif command == "PONG"
127
+ @nicks = parr.last.split("\n").uniq
128
+ @handles_list.clear
129
+ @nicks.each do |nick|
130
+ @handles_list.add_item(nick)
131
+ end
132
+ ping
133
+ elsif command == "HANDLES"
134
+ @nicks = parr.last.split("\n").uniq
135
+ @handles_list.clear
136
+ @nicks.each do |nick|
137
+ @handles_list.add_item(nick)
138
+ end
139
+ get_log
140
+ elsif command == "BUFFER"
141
+ puts "got log"
142
+ buffer = parr[1]
143
+ unless buffer == "" || buffer == nil
144
+ @chat_buffer = buffer
145
+ update_and_scroll
146
+ #output_to_chat_window(buffer)
147
+ end
148
+ elsif command == "SAY"
149
+ handle = parr[1]
150
+ msg = parr[2]
151
+ add_msg(handle, msg)
152
+ elsif command == "JOIN"
153
+ handle = parr[1]
154
+ self.nicks << handle
155
+ output_to_chat_window("#{handle} has entered\n")
156
+ @handles_list.add_item(handle)
157
+ elsif command == "LEAVE"
158
+ handle = parr[1]
159
+ output_to_chat_window("#{handle} has exited\n")
160
+ self.nicks.delete(handle)
161
+ @handles_list.remove_item(handle)
162
+ elsif command == "ALERT"
163
+ # if you get an alert
164
+ # you logged in wrong
165
+ # native alerts
166
+ # are not part of
167
+ # chat experience
168
+ text = parr[1]
169
+ alert(text)
170
+
171
+ return_to_server_list
172
+ end
173
+ end
174
+
175
+
176
+ def send_message(opcode, args)
177
+ msg = opcode + "::!!::" + args.join("::!!::")
178
+ msg = msg.force_encoding("UTF-8")
179
+ sock_send @ts, msg
180
+ end
181
+
182
+ def alert(msg)
183
+ Qt::MessageBox.critical(self, "Alert!", msg)
184
+ end
185
+
186
+ def sock_send io, msg
187
+ begin
188
+ $stderr.print "#{msg}\n"
189
+ msg = "#{msg}\0"
190
+ io.send msg, 0
191
+ rescue
192
+ autoreconnect
193
+ end
194
+ end
195
+
196
+ def post_message(message)
197
+ send_message "MESSAGE", [message, @chat_token]
198
+ add_msg(self.handle, message)
199
+ end
200
+
201
+ def add_msg(handle, message)
202
+ if @handle != handle && message.include?(@handle)
203
+ emit beep
204
+ end
205
+ msg = "#{handle}: #{message}\n"
206
+ output_to_chat_window(msg)
207
+ end
208
+
209
+ def get_log
210
+ send_message "GETBUFFER", [@chat_token]
211
+ end
212
+
213
+ def get_handles
214
+ send_message "GETHANDLES", [@chat_token]
215
+ end
216
+
217
+ def sign_out
218
+ send_message "SIGNOFF", [@chat_token]
219
+ @ts.close
220
+ end
221
+
222
+ def ping
223
+ @last_ping = Time.now
224
+ send_message("PING", [@chat_token])
225
+ end
226
+
227
+ def log str
228
+ puts str
229
+ #output_to_chat_window(str)
230
+ end
231
+
232
+ def output_to_chat_window str
233
+ @mutex.synchronize do
234
+ @chat_buffer += "#{str}"
235
+ update_and_scroll
236
+ end
237
+ end
238
+
239
+ end
240
+
241
+
242
+
243
+ class ServerList < Qt::Widget
244
+
245
+ signals :updateTitle
246
+
247
+ def initialize(parent=nil)
248
+ super parent
249
+ loader = Qt::UiLoader.new
250
+ file = Qt::File.new 'ServerList.ui' do
251
+ open Qt::File::ReadOnly
252
+ end
253
+ window = loader.load file
254
+ file.close
255
+
256
+ @pstore = PStore.new("gchat2pro.pstore")
257
+
258
+ @sl = window.findChild(Qt::ListWidget, "listWidget")
259
+ @handle = window.findChild(Qt::LineEdit, "lineEdit")
260
+ @host = window.findChild(Qt::LineEdit, "lineEdit_2")
261
+ @port = window.findChild(Qt::LineEdit, "lineEdit_3")
262
+ @password = window.findChild(Qt::LineEdit, "lineEdit_4")
263
+ @refresh = window.findChild(Qt::PushButton, "pushButton")
264
+ @connect = window.findChild(Qt::PushButton, "pushButton_2")
265
+
266
+ @sl.connect(SIGNAL "currentTextChanged(const QString&)") { |item| get_info(item) }
267
+ @refresh.connect(SIGNAL :clicked) { refresh }
268
+ @connect.connect(SIGNAL :clicked) { connect }
269
+
270
+ self.layout = Qt::VBoxLayout.new do |l|
271
+ l.addWidget(window)
272
+ end
273
+
274
+ self.windowTitle = tr("Server List")
275
+
276
+ get_servers
277
+
278
+ load_prefs
279
+ end
280
+
281
+ def refresh
282
+ @sl.clear
283
+ get_servers
284
+ end
285
+
286
+ def load_prefs
287
+ begin
288
+ @pstore.transaction do
289
+ @handle.text = @pstore["handle"] || ""
290
+ @host.text = @pstore["host"] || ""
291
+ @port.text = @pstore["port"] || ""
292
+ end
293
+ rescue
294
+ puts "no pstore yet"
295
+ end
296
+ end
297
+
298
+ def save_prefs
299
+ @pstore.transaction do
300
+ @pstore["handle"] = @handle.text
301
+ @pstore["host"] = @host.text
302
+ @pstore["port"] = @port.text
303
+ end
304
+ end
305
+
306
+ def get_info(name)
307
+ if name != "" && name != nil
308
+ row = @names.index(name)
309
+ @host.text = @server_list_hash[row][:host]
310
+ @port.text = @server_list_hash[row][:port]
311
+ end
312
+ end
313
+
314
+
315
+ def get_servers
316
+
317
+ Thread.new do
318
+ @server_list_hash = Net::HTTP.get('nexusnet.herokuapp.com', '/msl').
319
+ split("\n").
320
+ collect do |s|
321
+ par = s.split("-!!!-")
322
+ {:host => par[1], :name => par[0], :port => par[2]}
323
+ end
324
+
325
+
326
+ @names = @server_list_hash.map { |i| i[:name] }
327
+
328
+ update_servers
329
+ end
330
+
331
+ end
332
+
333
+ def update_servers
334
+ @sl.clear
335
+ @names.each do |name|
336
+ @sl.add_item(name)
337
+ end
338
+ end
339
+
340
+
341
+ def connect
342
+ # save defaults
343
+ save_prefs
344
+ self.hide
345
+ gc = GlobalChat.new(@handle.text, @host.text, @port.text, @password.text)
346
+ gc.show
347
+ end
348
+
349
+ end
350
+
351
+
352
+ class GlobalChat < Qt::Widget
353
+
354
+ attr_accessor :handles, :chat_window_text, :chat_message, :gcc
355
+
356
+ def initialize(handle, host, port, password, parent=nil)
357
+ super parent
358
+
359
+ block=Proc.new{ Thread.pass }
360
+ timer=Qt::Timer.new(window)
361
+ invoke=Qt::BlockInvocation.new(timer, block, "invoke()")
362
+ Qt::Object.connect(timer, SIGNAL("timeout()"), invoke, SLOT("invoke()"))
363
+ timer.start(1)
364
+
365
+ loader = Qt::UiLoader.new
366
+ file = Qt::File.new 'GlobalChat.ui' do
367
+ open Qt::File::ReadOnly
368
+ end
369
+ window = loader.load file
370
+ file.close
371
+
372
+ @handles_list = window.findChild(Qt::ListWidget, "listWidget")
373
+ @chat_window_text = window.findChild(Qt::TextEdit, "textEdit")
374
+ @chat_message = window.findChild(Qt::LineEdit, "lineEdit")
375
+
376
+ self.layout = Qt::VBoxLayout.new do |l|
377
+ l.addWidget(window)
378
+ end
379
+
380
+ self.windowTitle = tr("GlobalChat")
381
+
382
+ # UI ETC
383
+ @chat_message.connect(SIGNAL :returnPressed) { @gcc.sendMessage }
384
+ @handles_list.connect(SIGNAL "currentTextChanged(const QString&)") { |item| foghornMe(item) }
385
+
386
+ @gcc = GlobalChatController.new
387
+
388
+ @gcc.connect(SIGNAL :updateChatViews) { updateChatViews }
389
+ @gcc.connect(SIGNAL :updateTitles) { updateTitles }
390
+ @gcc.connect(SIGNAL :beep) { beep }
391
+
392
+ at_exit do
393
+ @gcc.sign_out
394
+ end
395
+
396
+ # binding.pry
397
+ Thread.new do
398
+ @gcc.handle = handle
399
+ @gcc.host = host
400
+ @gcc.port = port
401
+ @gcc.password = password
402
+ @gcc.nicks = []
403
+ @gcc.chat_buffer = ""
404
+ @gcc.handles_list = @handles_list
405
+ @gcc.chat_message = @chat_message
406
+ @gcc.chat_window_text = @chat_window_text
407
+ @gcc.autoreconnect unless @gcc.sign_on
408
+ end
409
+
410
+ end
411
+
412
+ def foghornMe(name)
413
+ if !(name == "") && !(name == nil)
414
+ @chat_message.text = "#{name}: "
415
+ @chat_message.setFocus
416
+ end
417
+ end
418
+
419
+ def beep
420
+ puts "\a"
421
+ end
422
+
423
+ def updateTitles
424
+ self.windowTitle = @gcc.server_name
425
+ end
426
+
427
+ def updateChatViews
428
+ @chat_window_text.text = @gcc.chat_buffer
429
+ @chat_window_text.verticalScrollBar.setSliderPosition(@chat_window_text.verticalScrollBar.maximum)
430
+ end
431
+
432
+ end
433
+
434
+
435
+ app = Qt::Application.new ARGV
436
+ # Qt.debug_level = Qt::DebugLevel::High
437
+ sl = ServerList.new
438
+ sl.show
439
+ app.exec
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/gc2-qtruby/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jonathan \"jsilver1er\" Silverman"]
6
+ gem.email = ["jsilverone@me.com"]
7
+ gem.description = %q{GlobalChat 2 Pro Chat Client}
8
+ gem.summary = %q{QTRuby crossplatform version}
9
+ gem.homepage = "http://globalchat2.net"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = 'globalchat'
13
+ gem.add_dependency('qtbindings', '>= 4.8.3.0')
14
+ gem.name = "globalchat"
15
+ gem.require_paths = ["."]
16
+ gem.version = Gc2::Qtruby::VERSION
17
+ end
data/gchat2pro.pstore ADDED
@@ -0,0 +1 @@
1
+ {" handle"