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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
#################################################################################
# This file is part of Spheres.
# Copyright (C) 2019 Jesusalva
# 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.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#################################################################################
# Chat controller
# TODO: Pub interface, using irc_send() and irc_buffer
init python:
irc=None
irc_online=False
def irc_open():
if not persistent.irc_enable:
return
global irc, irc_buffer, irc_nick, irc_auth, irc_channel, irc_online
import socket, sys, random
reload(sys)
sys.setdefaultencoding('utf8')
irc_online=False
server = "irc.freenode.org"
irc_channel = "#tmw2-spheres"
# TODO: Replace this with some uuid4()?
irc_nick = "GS_" + get_token()[:3] + str(random.randint(1, 10000))
irc_auth=IRC_AUTH_NONE
irc_buffer=[]
irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
stdout("\nConnecting to:" + server)
irc.connect((server, 6667))
return
def irc_receive(raw):
global irc_buffer
sender="IRC"
# Control buffer length
if (len(irc_buffer) >= MAX_IRC_BUFFER):
nil=irc_buffer.pop(0)
del nil
# Find sender if not supplied
try:
p1=raw.find('<')+1
p2=raw.find('>')
if p2 <= p1:
raise Exception("Invalid sender")
sender=raw[p1:p2]
except:
try:
p1=raw.find("!")
sender="IRC."+raw[1:p1]
except:
sender="IRC"
# Extract message
try:
p1=raw.find(" :") # Perhaps we're looking for ">" instead
msg=raw[p1:]
except:
msg="Unparseable"
# UNIX format
msg=msg.replace('\r', '')
irc_buffer.append((sender, msg))
return
def irc_send(sender, msg):
global irc, irc_channel, irc_online
if not irc_online:
return False
try:
irc.send("PRIVMSG %s :<%s> %s\n" % (irc_channel, sender, msg))
irc_buffer.append((sender, msg))
return True
except:
return False
def irc_kill():
global irc, irc_online
if irc_online:
irc.send("QUIT :I have to go for now!\n")
stdout("[IRC] Closing connection normally...")
irc.shutdown(2)
irc.close()
irc_online=False
stdout("[IRC] IRC Bridge is now Offline.")
#del irc
irc=None
return
def irc_loop():
if not persistent.irc_enable:
return
global irc, irc_buffer, irc_nick, irc_auth, irc_channel, irc_online
if irc is None:
irc_open()
try:
while 1:
text = irc.recv(2048)
if len(text) > 0:
if debug:
stdout("[IRC] %s" % text)
else:
continue
# Handle ping requests
if text.find("PING") != -1:
irc.send("PONG " + text.split()[1] + "\n")
# Authentication: Step 1
if irc_auth == IRC_AUTH_NONE:
irc.send("USER " + irc_nick + " " + irc_nick + " " + irc_nick + " :This is a fun bot\n")
irc_auth=IRC_AUTH_USER
continue
# Authentication: Step 2
if irc_auth == IRC_AUTH_USER:
irc.send("NICK " + irc_nick + "\n")
irc_auth=IRC_AUTH_NICK
continue
# Authentication: Step 3
if text.find("255 " + irc_nick) != -1:
irc.send("JOIN " + irc_channel + "\n")
if text.find("376 " + irc_nick) != -1:
if irc_auth == IRC_AUTH_NICK:
irc_auth=IRC_AUTH_CHAN
irc_online=True
else:
stdout("[IRC] Erroneous Authentication on 376 message")
irc_online=True
if irc_auth == IRC_AUTH_CHAN:
# IRC Syntax
# :nick!hostname PRIVMSG #tmw2-spheres :<nickname> msg
# We should use <nickname>, not :nick!
# TODO: Handle CTCP ACTION
if text.find(irc_channel) != -1:
if "PRIVMSG" in text:
irc_receive(text)
# Handle disconnections
if not irc_online:
raise Exception("Connection terminated.")
finally:
try:
irc.send("QUIT :I have to go for now!\n")
irc.shutdown(2)
irc.close()
except:
stdout("[IRC] [ERROR] Connection was already closed.")
stdout("\n")
stdout("Closing IRC connection...")
irc=None
return
screen pub():
frame:
background Frame("gui/frame.png", 0, 0)
xalign 0.5
yalign 0.5
ymargin 15
ypadding 10
xmargin 10
vbox:
spacing 30
textbutton _("Exit") action Return("")
label _("PUB RAID - NOT YET IMPLEMENTED")
null height 20
viewport:
#child_size (0.4, 0.8)
mousewheel True
draggable True
arrowkeys True
xfill False
scrollbars "vertical"
vbox:
xalign 0.5
spacing 5
label _("%s" % persistent.nickname)
null height 40
showif irc_online:
for chat in irc_buffer:
label _("%s: {size=22}%s{/size}" % (chat[0], chat[1].replace("<%s>" % chat[0], "")))
null height 40
input:
id "msgmsg"
color ((128, 128, 128, 220))
italic True
size 26
copypaste True
allow "qwertyuiopasdfghjklzxcvbnm QWERTYUIOPASDFGHJKKLZXCVBNM,.?!+-=:;'()"
textbutton _("Send") action None # Function(irc_send)
else:
if persistent.irc_enable:
label _("Connecting...")
else:
label _("IRC Integration is not active.")
# FIXME inform if IRC is disabled
# Ask user to comply with Freenode TOS etc.
timer 1.0 action Function(renpy.restart_interaction) repeat True
|