globalchat 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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"