Full database integration. No more json!
Showing
4 changed files
with
431 additions
and
216 deletions
No preview for this file type
1 | import json | 1 | import json |
2 | import sqlite3 | 2 | import sqlite3 |
3 | import datetime | ||
3 | 4 | ||
4 | conn = sqlite3.connect('db.sqlite3') | 5 | conn = sqlite3.connect('db.sqlite3') |
5 | 6 | ||
... | @@ -65,6 +66,152 @@ def import_messages(conn): | ... | @@ -65,6 +66,152 @@ def import_messages(conn): |
65 | pass | 66 | pass |
66 | conn.commit() | 67 | conn.commit() |
67 | 68 | ||
68 | import_jokes(conn) | ||
69 | import_fortunes(conn) | ||
70 | import_messages(conn) | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
69 | def get_game_names(game_id_list): | ||
70 | games_file = 'games.json' | ||
71 | json_data=open(games_file).read() | ||
72 | data = json.loads(json_data) | ||
73 | result = [] | ||
74 | for game_id in game_id_list: | ||
75 | if isinstance(game_id, str) and not game_id.isdigit(): | ||
76 | result.append(game_id) | ||
77 | continue | ||
78 | name_set = False | ||
79 | for game in data: | ||
80 | if game['id'] == game_id: | ||
81 | result.append(game['name']) | ||
82 | name_set = True | ||
83 | return result | ||
84 | |||
85 | def dict_factory(cursor, row): | ||
86 | if row == None: | ||
87 | return None | ||
88 | d = {} | ||
89 | for idx, col in enumerate(cursor.description): | ||
90 | d[col[0]] = row[idx] | ||
91 | return d | ||
92 | |||
93 | def db_get_member(discord_id=None, username=None): | ||
94 | # Do a lookup by ID, if it's found but the name doesn't match then add a row to aliases with the previous name and change the member name | ||
95 | c = conn.cursor() | ||
96 | result = None | ||
97 | if discord_id: | ||
98 | result = c.execute("SELECT member_id, member_name, discord_id, discord_mention, is_afk, afk_at, status, prev_status, status_change_at, current_game FROM members WHERE discord_id = ?;", (discord_id,)).fetchone() | ||
99 | if username: | ||
100 | result = c.execute("SELECT member_id, member_name, discord_id, discord_mention, is_afk, afk_at, status, prev_status, status_change_at, current_game FROM members WHERE member_name = ?;", (username,)).fetchone() | ||
101 | return dict_factory(c, result) | ||
102 | def log(message): | ||
103 | print("{} - {}".format(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'), message)) | ||
104 | |||
105 | def db_add_game(member_id, game_name): | ||
106 | # Do a lookup by ID, if it's found but the name doesn't match then add a row to aliases with the previous name and change the member name | ||
107 | c = conn.cursor() | ||
108 | games = c.execute("SELECT game_id FROM games WHERE game_name = ?;", (game_name,)).fetchone() | ||
109 | db_game_id = 0 | ||
110 | if not games: | ||
111 | log("Adding Game: {}".format(game_name,)) | ||
112 | c.execute("INSERT INTO games(game_name) VALUES(?);", (game_name,)) | ||
113 | conn.commit() | ||
114 | db_game_id = c.execute("select last_insert_rowid();").fetchone()[0] | ||
115 | else: | ||
116 | db_game_id = games[0] | ||
117 | #log("DB Game ID: {}".format(db_game_id,)) | ||
118 | member_games = c.execute("SELECT launch_count FROM xmember_games WHERE game_id = ? AND member_id = ?;", (db_game_id, member_id)).fetchone() | ||
119 | if not member_games: | ||
120 | #log("Inserting Member Games: {}, {}".format(db_game_id, member_id)) | ||
121 | c.execute("INSERT INTO xmember_games(game_id, member_id, launch_count) VALUES(?, ?, 1);", (db_game_id, member_id)) | ||
122 | conn.commit() | ||
123 | else: | ||
124 | #log("Updating Member Games: {}, {}".format(db_game_id, member_id)) | ||
125 | c.execute("UPDATE xmember_games SET launch_count = launch_count + 1 WHERE game_id = ? AND member_id = ?;", (db_game_id, member_id)) | ||
126 | conn.commit() | ||
127 | |||
128 | def db_create_member(member): | ||
129 | # Do a lookup by ID, if it's found but the name doesn't match then add a row to aliases with the previous name and change the member name | ||
130 | c = conn.cursor() | ||
131 | c.execute("""INSERT INTO members (member_name, discord_id, discord_mention, | ||
132 | is_afk, afk_at, status, prev_status, | ||
133 | status_change_at, current_game) | ||
134 | VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);""", (member.name.lower(), | ||
135 | member.id, member.mention, | ||
136 | 0, datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'), | ||
137 | 'online', 'offline', | ||
138 | datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'), | ||
139 | member.game_id)) | ||
140 | conn.commit() | ||
141 | if member.game_id != None: | ||
142 | db_add_game(db_get_member(member.id)['member_id'], member.game_id) | ||
143 | class Member: | ||
144 | pass | ||
145 | def import_games(conn): | ||
146 | games_file = 'games.json' | ||
147 | members_file = 'members.json' | ||
148 | |||
149 | json_data=open(members_file).read() | ||
150 | member_data = json.loads(json_data) | ||
151 | |||
152 | json_data=open(games_file).read() | ||
153 | game_data = json.loads(json_data) | ||
154 | |||
155 | c = conn.cursor() | ||
156 | user_games = {} | ||
157 | for username in member_data: | ||
158 | if 'games_played' in member_data[username]: | ||
159 | for game_id in member_data[username]['games_played']: | ||
160 | if (game_id != 'None' and game_id != 0): | ||
161 | if username not in user_games: | ||
162 | user_games[username] = [] | ||
163 | if game_id: | ||
164 | if isinstance( game_id, int) or game_id.isdigit(): | ||
165 | game_names = get_game_names([game_id]) | ||
166 | #print(game_names) | ||
167 | if len(game_names) > 0: | ||
168 | user_games[username].append(game_names[0]) | ||
169 | else: | ||
170 | user_games[username].append(game_id) | ||
171 | #print(user_games) | ||
172 | for username, game_list in user_games.iteritems(): | ||
173 | member = db_get_member(username=username) | ||
174 | if member: | ||
175 | for game in game_list: | ||
176 | db_add_game(member['member_id'], game) | ||
177 | print("Added Game: {} - {}".format(member['member_id'], game)) | ||
178 | else: | ||
179 | if 'id' not in member_data[username]: | ||
180 | continue | ||
181 | member_to_create = Member() | ||
182 | member_to_create.name = username | ||
183 | member_to_create.id = member_data[username]['id'] | ||
184 | member_to_create.mention = member_data[username]['mention'] | ||
185 | member_to_create.game_id = None | ||
186 | db_create_member(member_to_create) | ||
187 | print("missing {}".format(byteify(username))) | ||
188 | print(member_to_create) | ||
189 | |||
190 | |||
191 | |||
192 | # 'id': user_id, | ||
193 | # 'mention': mention, | ||
194 | # 'is_afk': is_afk, | ||
195 | # 'afk_at': afk_at, | ||
196 | # 'status': status, | ||
197 | # 'prev_status': prev_status, | ||
198 | # 'status_change_at': status_change_at, | ||
199 | # 'game_id': game_id, | ||
200 | # 'games_played': games_played, | ||
201 | # 'aliases': aliases | ||
202 | |||
203 | |||
204 | # for username in data: | ||
205 | # print("Username: %s" % username) | ||
206 | # for author in data[username]: | ||
207 | # try: | ||
208 | # c.execute("INSERT INTO messages (message, delivery_time, channel, message_from, message_to, user_id) VALUES (?, ?, ?, ?, ?, ?)", (data[username][author]['message'], data[username][author]['delivery_time'],data[username][author]['channel'], author, username, data[username][author]['user_id'])) | ||
209 | # except Exception as e: | ||
210 | # print(e) | ||
211 | # pass | ||
212 | # conn.commit() | ||
213 | |||
214 | #import_jokes(conn) | ||
215 | #import_fortunes(conn) | ||
216 | #import_messages(conn) | ||
217 | #import_games(conn) | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -3,6 +3,7 @@ import discord | ... | @@ -3,6 +3,7 @@ import discord |
3 | import random | 3 | import random |
4 | import datetime | 4 | import datetime |
5 | import re | 5 | import re |
6 | import operator | ||
6 | 7 | ||
7 | import traceback | 8 | import traceback |
8 | import sys | 9 | import sys |
... | @@ -34,6 +35,14 @@ muted_until = datetime.datetime.now() | ... | @@ -34,6 +35,14 @@ muted_until = datetime.datetime.now() |
34 | client = discord.Client() | 35 | client = discord.Client() |
35 | wolf = {} | 36 | wolf = {} |
36 | 37 | ||
38 | |||
39 | ##################### | ||
40 | ## Utility Functions | ||
41 | ##################### | ||
42 | |||
43 | def log(message): | ||
44 | print("{} - {}".format(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'), message)) | ||
45 | |||
37 | def format_exception(e): | 46 | def format_exception(e): |
38 | exception_list = traceback.format_stack() | 47 | exception_list = traceback.format_stack() |
39 | exception_list = exception_list[:-2] | 48 | exception_list = exception_list[:-2] |
... | @@ -89,76 +98,228 @@ def search_google_images(query, animated=False): | ... | @@ -89,76 +98,228 @@ def search_google_images(query, animated=False): |
89 | return search_result | 98 | return search_result |
90 | return "boo you fail.." | 99 | return "boo you fail.." |
91 | 100 | ||
92 | @client.event | 101 | ################## |
93 | def on_socket_raw_send(payload, binary=False): | 102 | ## Database Calls |
94 | check_msg_queue() | 103 | ################## |
95 | 104 | ||
96 | @client.event | 105 | # Converts a row into a dictionary |
97 | def on_status(member): | 106 | def dict_factory(cursor, row): |
98 | #print("Status Changed %s" % (member,)) | 107 | if row == None: |
99 | try: | 108 | return None |
100 | json_data=open(member_status).read() | 109 | d = {} |
101 | data = json.loads(json_data) | 110 | for idx, col in enumerate(cursor.description): |
102 | print(json_data) | 111 | d[col[0]] = row[idx] |
103 | except ValueError: | 112 | return d |
104 | data = {} | 113 | |
105 | if not data: | 114 | def db_add_message(message, delivery_time, channel, message_from, message_to, user_id): |
106 | data = {} | 115 | c = conn.cursor() |
107 | try: | 116 | c.execute("""INSERT INTO messages(message, delivery_time, channel, message_from, message_to, user_id) |
108 | username = member.name.lower() | 117 | VALUES(?, ?, ?, ?, ?, ?);""", (message, delivery_time, channel, message_from, message_to, user_id)) |
109 | user_id = member.id | 118 | conn.commit() |
110 | mention = member.mention() | 119 | |
111 | if username in data: | 120 | def db_delete_sent_message(message_id): |
112 | is_afk = data[username]['is_afk'] | 121 | c = conn.cursor() |
113 | afk_at = data[username]['afk_at'] | 122 | c.execute("DELETE FROM messages WHERE message_id = ?;", (message_id,)) |
114 | status = data[username]['status'] | 123 | conn.commit() |
115 | prev_status = data[username]['prev_status'] | 124 | |
116 | status_change_at = data[username]['status_change_at'] | 125 | def db_get_aliases(member_id): |
117 | game_id = data[username]['game_id'] | 126 | c = conn.cursor() |
118 | games_played = data[username]['games_played'] | 127 | aliases = c.execute("SELECT alias_name FROM aliases WHERE member_id = ?;", (member_id,)).fetchall() |
119 | aliases = data[username]['aliases'] | 128 | if aliases: |
129 | alias_list = [] | ||
130 | for alias in aliases: | ||
131 | alias_list.append(alias[0]) | ||
132 | return alias_list | ||
120 | else: | 133 | else: |
121 | is_afk = False | 134 | return None |
122 | afk_at = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') | 135 | |
123 | status = 'online' | 136 | def db_add_aliases(member_id, alias_name): |
124 | prev_status = 'offline' | 137 | c = conn.cursor() |
125 | status_change_at = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') | 138 | c.execute("INSERT INTO aliases(alias_name, member_id) VALUES (?, ?);", (alias_name, member_id,)) |
126 | game_id = None | 139 | conn.commit() |
127 | games_played = [] | 140 | |
128 | aliases = [] | 141 | def db_get_messages(): |
142 | msg_conn = sqlite3.connect('db.sqlite3') | ||
143 | |||
144 | c = msg_conn.cursor() | ||
145 | messages = c.execute("SELECT * FROM messages WHERE datetime('now') >= datetime( replace(delivery_time, '/', '-'));").fetchall() | ||
146 | if messages: | ||
147 | db_messages = [] | ||
148 | for message in messages: | ||
149 | db_messages.append(dict_factory(c, message)) | ||
150 | else: | ||
151 | db_messages = None | ||
152 | msg_conn.close() | ||
153 | return db_messages | ||
154 | |||
155 | def db_get_whoplayed(game_name): | ||
156 | c = conn.cursor() | ||
157 | members = c.execute("""SELECT m.member_name, xmg.launch_count | ||
158 | FROM members m | ||
159 | INNER JOIN xmember_games xmg ON | ||
160 | m.member_id = xmg.member_id | ||
161 | INNER JOIN games g ON | ||
162 | g.game_id = xmg.game_id | ||
163 | WHERE g.game_name COLLATE nocase = ? | ||
164 | Order By xmg.launch_count, m.member_name DESC;""", (game_name,)).fetchall() | ||
165 | member_list = {} | ||
166 | for member in members: | ||
167 | member_list[member[0]] = member[1] | ||
168 | #log(member_list) | ||
169 | return sorted(member_list.items(), reverse=True, key=operator.itemgetter(1)) | ||
170 | #return sorted(member_list, reverse=True, key=lambda tup: tup[1]) | ||
171 | |||
172 | def db_get_games(username): | ||
173 | c = conn.cursor() | ||
174 | games = c.execute("""SELECT g.game_name, xmg.launch_count FROM games g | ||
175 | INNER JOIN xmember_games xmg ON | ||
176 | g.game_id = xmg.game_id | ||
177 | INNER JOIN members m ON | ||
178 | m.member_id = xmg.member_id | ||
179 | WHERE m.member_name COLLATE nocase = ?;""", (username,)).fetchall() | ||
180 | games_list = {} | ||
181 | for game in games: | ||
182 | games_list[game[0]] = game[1] | ||
183 | return games_list | ||
184 | |||
185 | def db_get_games_list(limit): | ||
186 | c = conn.cursor() | ||
187 | games_list = c.execute("""SELECT g.game_name, count(DISTINCT xmg.member_id) | ||
188 | FROM games g | ||
189 | INNER JOIN xmember_games xmg ON | ||
190 | g.game_id = xmg.game_id | ||
191 | Group By xmg.game_id | ||
192 | Order By COUNT(DISTINCT xmg.member_id) DESC | ||
193 | LIMIT ?""", (limit,)).fetchall() | ||
194 | return games_list | ||
195 | |||
196 | def db_add_game(member_id, game_name): | ||
197 | # Do a lookup by ID, if it's found but the name doesn't match then add a row to aliases with the previous name and change the member name | ||
198 | c = conn.cursor() | ||
199 | games = c.execute("SELECT game_id FROM games WHERE game_name = ?;", (game_name,)).fetchone() | ||
200 | db_game_id = 0 | ||
201 | if not games: | ||
202 | log("Adding Game: {}".format(game_name,)) | ||
203 | c.execute("INSERT INTO games(game_name) VALUES(?);", (game_name,)) | ||
204 | conn.commit() | ||
205 | db_game_id = c.execute("select last_insert_rowid();").fetchone()[0] | ||
206 | else: | ||
207 | db_game_id = games[0] | ||
208 | #log("DB Game ID: {}".format(db_game_id,)) | ||
209 | member_games = c.execute("SELECT launch_count FROM xmember_games WHERE game_id = ? AND member_id = ?;", (db_game_id, member_id)).fetchone() | ||
210 | if not member_games: | ||
211 | #log("Inserting Member Games: {}, {}".format(db_game_id, member_id)) | ||
212 | c.execute("INSERT INTO xmember_games(game_id, member_id, launch_count) VALUES(?, ?, 1);", (db_game_id, member_id)) | ||
213 | conn.commit() | ||
214 | else: | ||
215 | #log("Updating Member Games: {}, {}".format(db_game_id, member_id)) | ||
216 | c.execute("UPDATE xmember_games SET launch_count = launch_count + 1 WHERE game_id = ? AND member_id = ?;", (db_game_id, member_id)) | ||
217 | conn.commit() | ||
218 | |||
219 | def db_get_member(discord_id=None, username=None): | ||
220 | # Do a lookup by ID, if it's found but the name doesn't match then add a row to aliases with the previous name and change the member name | ||
221 | member_conn = sqlite3.connect('db.sqlite3') | ||
222 | |||
223 | c = member_conn.cursor() | ||
224 | result = None | ||
225 | if discord_id: | ||
226 | result = c.execute("SELECT member_id, member_name, discord_id, discord_mention, is_afk, afk_at, status, prev_status, status_change_at, current_game FROM members WHERE discord_id = ?;", (discord_id,)).fetchone() | ||
227 | if username: | ||
228 | result = c.execute("SELECT member_id, member_name, discord_id, discord_mention, is_afk, afk_at, status, prev_status, status_change_at, current_game FROM members WHERE member_name = ?;", (username,)).fetchone() | ||
229 | member_conn.close() | ||
230 | return dict_factory(c, result) | ||
231 | |||
232 | def db_create_member(member): | ||
233 | # Do a lookup by ID, if it's found but the name doesn't match then add a row to aliases with the previous name and change the member name | ||
234 | c = conn.cursor() | ||
235 | c.execute("""INSERT INTO members (member_name, discord_id, discord_mention, | ||
236 | is_afk, afk_at, status, prev_status, | ||
237 | status_change_at, current_game) | ||
238 | VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);""", (member.name.lower(), | ||
239 | member.id, member.mention(), | ||
240 | 0, datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'), | ||
241 | 'online', 'offline', | ||
242 | datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'), | ||
243 | member.game_id)) | ||
244 | conn.commit() | ||
245 | if member.game_id != None: | ||
246 | db_add_game(db_get_member(member.id)['member_id'], member.game_id) | ||
247 | |||
248 | def db_update_member(member, db_member): | ||
249 | # Do a lookup by ID, if it's found but the name doesn't match then add a row to aliases with the previous name and change the member name | ||
250 | db_member_id = db_member['member_id'] | ||
251 | db_membername = db_member['member_name'] | ||
252 | status = db_member['status'] | ||
253 | prev_status = db_member['prev_status'] | ||
254 | |||
255 | c = conn.cursor() | ||
256 | if member.name.lower() != db_membername: | ||
257 | log("Member Name changed! {} to {}".format(db_membername, member.name.lower())) | ||
258 | c.execute("UPDATE members SET member_name = ? WHERE discord_id = ?;", (member.name.lower(), member.id,)) | ||
259 | conn.commit() | ||
260 | |||
261 | aliases = c.execute("SELECT * FROM aliases WHERE alias_name = ? AND member_id = ?;", (db_membername, db_member_id)).fetchone() | ||
262 | log("Alias list for user: {}".format(aliases)) | ||
263 | if aliases == None: | ||
264 | log("creating new alias: {}, {}".format(db_membername, db_member_id)) | ||
265 | c.execute("INSERT INTO aliases (alias_name, member_id) VALUES (?, ?);", (db_membername, db_member_id)) | ||
266 | conn.commit() | ||
267 | |||
129 | if member.status == 'idle': | 268 | if member.status == 'idle': |
130 | afk_at = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') | 269 | afk_at = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') |
131 | is_afk = True | 270 | is_afk = True |
132 | else: | 271 | else: |
133 | is_afk = False | 272 | is_afk = False |
273 | status_change_at = None | ||
134 | if status != member.status: | 274 | if status != member.status: |
135 | prev_status = status | 275 | prev_status = status |
136 | status = member.status | 276 | status = member.status |
137 | status_change_at = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') | 277 | status_change_at = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') |
138 | if game_id != member.game_id: | 278 | if is_afk: |
139 | game_id = member.game_id | 279 | #log("is afk") |
140 | if game_id not in games_played: | 280 | c.execute("""UPDATE members |
141 | games_played.append(game_id) | 281 | SET is_afk = ?, afk_at = ?, status = ?, |
142 | data[username] = { | 282 | prev_status = ?, status_change_at = ? |
143 | 'id': user_id, | 283 | WHERE discord_id = ?;""", (1, afk_at, status, prev_status, status_change_at, member.id)) |
144 | 'mention': mention, | 284 | conn.commit() |
145 | 'is_afk': is_afk, | 285 | else: |
146 | 'afk_at': afk_at, | 286 | #log("is not afk") |
147 | 'status': status, | 287 | c.execute("""UPDATE members |
148 | 'prev_status': prev_status, | 288 | SET is_afk = ?, status = ?, |
149 | 'status_change_at': status_change_at, | 289 | prev_status = ?, status_change_at = ? |
150 | 'game_id': game_id, | 290 | WHERE discord_id = ?;""", (0, status, prev_status, status_change_at, member.id)) |
151 | 'games_played': games_played, | 291 | conn.commit() |
152 | 'aliases': aliases | 292 | c.execute("UPDATE members SET current_game = ? WHERE discord_id = ?;", (member.game_id, member.id)) |
153 | } | 293 | conn.commit() |
154 | #print('Status Change: %s' % (data,)) | 294 | |
155 | jdata = json.dumps(data, ensure_ascii=False) | 295 | #log("Member: {} \nMember GameID: {} db Game id: {}".format(member, member.game_id, db_member['current_game'])) |
156 | except Exception as e: | 296 | if member.game_id != None and member.game_id != db_member['current_game']: |
157 | print('Error saving status change: %s' % (e),) | 297 | db_add_game(db_member['member_id'], member.game_id) |
158 | return | 298 | |
299 | ################# | ||
300 | ## Client Events | ||
301 | ################# | ||
302 | |||
303 | @client.event | ||
304 | def on_socket_raw_send(payload, binary=False): | ||
305 | check_msg_queue() | ||
306 | |||
307 | @client.event | ||
308 | def on_status(member): | ||
309 | try: | ||
310 | db_member = db_get_member(member.id) | ||
311 | #log(db_member) | ||
312 | if not db_member: | ||
313 | log("Creating new member: {}".format(member) ) | ||
314 | db_create_member(member) | ||
315 | else: | ||
316 | #log("Updating member: {}".format(member) ) | ||
317 | db_update_member(member, db_member) | ||
159 | 318 | ||
160 | open(member_status, 'wb+').write(jdata.encode('utf8')) | ||
161 | check_msg_queue() | 319 | check_msg_queue() |
320 | except Exception as e: | ||
321 | log("Exception: {}".format(format_exception(e))) | ||
322 | pass | ||
162 | 323 | ||
163 | def get_game_names(game_id_list): | 324 | def get_game_names(game_id_list): |
164 | json_data=open(games_file).read() | 325 | json_data=open(games_file).read() |
... | @@ -190,47 +351,22 @@ def get_mention_status(mention): | ... | @@ -190,47 +351,22 @@ def get_mention_status(mention): |
190 | return None | 351 | return None |
191 | 352 | ||
192 | def check_msg_queue(): | 353 | def check_msg_queue(): |
193 | print("checking messages") | 354 | #print("checking messages") |
355 | messages = db_get_messages() | ||
356 | if messages: | ||
357 | for message in messages: | ||
194 | try: | 358 | try: |
195 | json_data=open(deliveries_file).read() | 359 | member = db_get_member(filter(unicode.isalnum, message['message_to'])) |
196 | data = json.loads(json_data) | 360 | if member: |
197 | except ValueError: | 361 | if message['message_to'] == member['discord_mention']: |
198 | data = {} | 362 | print("Found Message: {} - {} - Status: {} Channel: {}".format(message['message_to'], member['discord_mention'], member['status'], message['channel'])) |
199 | if not data: | 363 | if member['status'] == 'online': |
200 | data = {} | 364 | client.send_message(Object(message['channel']), '{}, {} asked me to tell you "{}"'.format(message['message_to'], message['message_from'], message['message'])) |
201 | #print("Data: %s" % data) | 365 | db_delete_sent_message(message['message_id']) |
202 | new_data = {} | 366 | except Exception as e: |
203 | for username in data: | 367 | log("{}\nFailed to send message: {}".format(format_exception(e), message['message_id'],)) |
204 | for author in data[username]: | ||
205 | print("Message: %s" % data[username][author]) | ||
206 | delivery = datetime.datetime.strptime(data[username][author]['delivery_time'], '%Y/%m/%d %H:%M:%S') | ||
207 | if delivery <= datetime.datetime.now(): | ||
208 | offline = False | ||
209 | for member in client.get_all_members(): | ||
210 | print('MEMBER MENTION: %s USERNAME: %s' % (member.mention(), username)) | ||
211 | |||
212 | if username == member.mention(): | ||
213 | if member.status != 'online': | ||
214 | print('OFFLINE USER, TRY AGAIN LATER') | ||
215 | offline = True | ||
216 | break | ||
217 | if offline: | ||
218 | new_data[username] = {} | ||
219 | new_data[username][author] = data[username][author] | ||
220 | break | ||
221 | channel = Object(data[username][author]['channel']) | ||
222 | message = data[username][author]['message'] | ||
223 | client.send_message(channel, '{}, {} asked me to tell you "{}"'.format(username, author, message)) | ||
224 | else: | ||
225 | new_data[username] = {} | ||
226 | new_data[username][author] = data[username][author] | ||
227 | |||
228 | jdata = json.dumps(new_data, ensure_ascii=False) | ||
229 | #print("New Data: %s" % new_data) | ||
230 | open(deliveries_file, 'wb+').write(jdata.encode('utf8')) | ||
231 | return | 368 | return |
232 | 369 | ||
233 | |||
234 | @client.event | 370 | @client.event |
235 | def on_message(message): | 371 | def on_message(message): |
236 | #print message.content | 372 | #print message.content |
... | @@ -282,32 +418,26 @@ Stuff: | ... | @@ -282,32 +418,26 @@ Stuff: |
282 | return | 418 | return |
283 | 419 | ||
284 | if message.content.startswith('!lastseen'): | 420 | if message.content.startswith('!lastseen'): |
285 | data = None | ||
286 | try: | ||
287 | json_data=open(member_status).read() | ||
288 | data = json.loads(json_data) | ||
289 | except ValueError: | ||
290 | pass | ||
291 | if not data: | ||
292 | client.send_message(message.channel, 'I am a bit confused right now.. maybe I need more data. {}!'.format(message.author.mention())) | ||
293 | else: | ||
294 | username = message.content[10:].replace('@', '').lower() | 421 | username = message.content[10:].replace('@', '').lower() |
295 | if username in data: | 422 | member = db_get_member(username=username) |
423 | log(member) | ||
424 | if member: | ||
296 | out_string = '' | 425 | out_string = '' |
297 | if data[username]['is_afk'] == True: | 426 | if member['is_afk'] == 1: |
298 | out_string = 'Went AFK at: {}\n'.format(data[username]['afk_at']) | 427 | out_string = 'Went AFK at: {}\n'.format(member['afk_at']) |
299 | elif data[username]['status'] == 'offline': | 428 | elif member['status'] == 'offline': |
300 | out_string = 'Currently Offline\n' | 429 | out_string = 'Currently Offline\n' |
301 | else: | 430 | else: |
302 | out_string = 'Currently Online\n' | 431 | out_string = 'Currently Online\n' |
303 | out_string += 'Last Status: {} at {} which was {}\nPrevious Status: {}\n'.format(data[username]['status'], | 432 | out_string += 'Last Status: {} at {} which was {}\nPrevious Status: {}\n'.format(member['status'], |
304 | data[username]['status_change_at'], | 433 | member['status_change_at'], |
305 | human(datetime.datetime.strptime(data[username]['status_change_at'], '%Y/%m/%d %H:%M:%S')), | 434 | human(datetime.datetime.strptime(member['status_change_at'], '%Y/%m/%d %H:%M:%S')), |
306 | data[username]['prev_status']) | 435 | member['prev_status']) |
307 | 436 | ||
308 | client.send_message(message.channel, 'Last Information on {}:\n{}'.format(username, out_string)) | 437 | client.send_message(message.channel, 'Last Information on {}:\n{}'.format(username, out_string)) |
309 | else: | 438 | else: |
310 | client.send_message(message.channel, 'I don\'t have any data on {} yet {}'.format(username, message.author.mention())) | 439 | client.send_message(message.channel, 'I don\'t have any data on {} yet {}'.format(username, message.author.mention())) |
440 | return | ||
311 | 441 | ||
312 | if message.content.startswith('!shutup'): | 442 | if message.content.startswith('!shutup'): |
313 | muted_until = datetime.datetime.now() + datetime.timedelta(minutes=5) | 443 | muted_until = datetime.datetime.now() + datetime.timedelta(minutes=5) |
... | @@ -360,35 +490,16 @@ Stuff: | ... | @@ -360,35 +490,16 @@ Stuff: |
360 | client.send_message(message.channel, out_string) | 490 | client.send_message(message.channel, out_string) |
361 | return | 491 | return |
362 | 492 | ||
363 | if message.content.startswith('!gameslist'): | 493 | if message.content.startswith('!gameslist') or message.content.startswith('!gamelist') : |
364 | data = None | ||
365 | try: | ||
366 | json_data=open(member_status).read() | ||
367 | data = json.loads(json_data) | ||
368 | except ValueError: | ||
369 | pass | ||
370 | if not data: | ||
371 | client.send_message(message.channel, 'I am a bit confused right now.. maybe I need more data. {}!'.format(message.author.mention())) | ||
372 | else: | ||
373 | parts = message.content.split(' ') | 494 | parts = message.content.split(' ') |
374 | limit = 20 | 495 | limit = 20 |
375 | if len(parts) > 1 and parts[1].isdigit(): | 496 | if len(parts) > 1 and parts[1].isdigit(): |
376 | limit = int(parts[1]) | 497 | limit = int(parts[1]) |
498 | games_list = db_get_games_list(limit) | ||
377 | 499 | ||
378 | game_list = [] | ||
379 | for user in data: | ||
380 | if 'games_played' in data[user]: | ||
381 | #print('%s' % data[user]['games_played']) | ||
382 | |||
383 | game_list += data[user]['games_played'] | ||
384 | print('%s' % game_list) | ||
385 | games_sorted = leaders(get_game_names(game_list), top=limit) | ||
386 | print('%s' % games_sorted) | ||
387 | out_string = '' | 500 | out_string = '' |
388 | for game in games_sorted: | 501 | for game in games_list: |
389 | #print('%s' % game) | 502 | out_string += ' {} - {}\n'.format(game[1], byteify(game[0])) |
390 | out_string += ' {} - {}\n'.format(game[1], game[0]) | ||
391 | |||
392 | client.send_message(message.channel, 'The games I have seen people playing are: ') | 503 | client.send_message(message.channel, 'The games I have seen people playing are: ') |
393 | while len(out_string) > 0: | 504 | while len(out_string) > 0: |
394 | client.send_message(message.channel, out_string[:1900]) | 505 | client.send_message(message.channel, out_string[:1900]) |
... | @@ -397,99 +508,54 @@ Stuff: | ... | @@ -397,99 +508,54 @@ Stuff: |
397 | return | 508 | return |
398 | 509 | ||
399 | if message.content.startswith('!aliases'): | 510 | if message.content.startswith('!aliases'): |
400 | data = None | ||
401 | try: | ||
402 | json_data=open(member_status).read() | ||
403 | data = json.loads(json_data) | ||
404 | except ValueError: | ||
405 | pass | ||
406 | if not data: | ||
407 | client.send_message(message.channel, 'I am a bit confused right now.. maybe I need more data. {}!'.format(message.author.mention())) | ||
408 | else: | ||
409 | username = message.content[9:].replace('@', '').lower() | 511 | username = message.content[9:].replace('@', '').lower() |
410 | if username.strip() == '': | 512 | member = db_get_member(username=username) |
411 | client.send_message(message.channel, '{} please provide a username. !aliases <username>'.format(message.author.mention())) | 513 | if member: |
412 | return | 514 | aliases = db_get_aliases(member['member_id']) |
413 | if username in data and 'aliases' in data[username]: | 515 | if aliases: |
414 | client.send_message(message.channel, '{} has the following aliases: {}'.format(username, ', '.join(data[username]['aliases']))) | 516 | client.send_message(message.channel, '{} has the following aliases: {}'.format(username, ', '.join(aliases))) |
415 | else: | 517 | else: |
416 | client.send_message(message.channel, 'No known alises for {} yet {}'.format(username, message.author.mention())) | 518 | client.send_message(message.channel, 'No known alises for {} yet {}'.format(username, message.author.mention())) |
519 | else: | ||
520 | client.send_message(message.channel, 'I don\'t know who you are speaking of {}!'.format(message.author.mention())) | ||
417 | return | 521 | return |
418 | 522 | ||
419 | if message.content.startswith('!addalias'): | 523 | if message.content.startswith('!addalias'): |
420 | data = None | ||
421 | try: | ||
422 | json_data=open(member_status).read() | ||
423 | data = json.loads(json_data) | ||
424 | except ValueError: | ||
425 | pass | ||
426 | if not data: | ||
427 | client.send_message(message.channel, 'I am a bit confused right now.. maybe I need more data. {}!'.format(message.author.mention())) | ||
428 | else: | ||
429 | alias = message.content[10:] | 524 | alias = message.content[10:] |
430 | username = message.author.name.lower() | 525 | username = message.author.name.lower() |
431 | if username in data: | 526 | member = db_get_member(username=username) |
432 | if 'aliases' not in data[username]: | 527 | if member: |
433 | data[username]['aliases'] = [] | 528 | db_add_aliases(member['member_id'], alias) |
434 | data[username]['aliases'].append(alias) | ||
435 | jdata = json.dumps(data, ensure_ascii=False) | ||
436 | |||
437 | open(member_status, 'wb+').write(jdata.encode('utf8')) | ||
438 | client.send_message(message.channel, '{} has been added to your aliases'.format(alias)) | 529 | client.send_message(message.channel, '{} has been added to your aliases'.format(alias)) |
439 | else: | 530 | else: |
440 | client.send_message(message.channel, 'Something horrible happened and it is all your fault.') | 531 | client.send_message(message.channel, 'Something horrible happened and it is all your fault, try logging out / on again or play a game. (or fuck off i dunno i\'m just an error message. Who am I to tell you how to run your life...)') |
441 | return | 532 | return |
442 | 533 | ||
443 | if message.content.startswith('!games'): | 534 | if message.content.startswith('!games'): |
444 | data = None | ||
445 | try: | ||
446 | json_data=open(member_status).read() | ||
447 | data = json.loads(json_data) | ||
448 | except ValueError: | ||
449 | pass | ||
450 | if not data: | ||
451 | client.send_message(message.channel, 'I am a bit confused right now.. maybe I need more data. {}!'.format(message.author.mention())) | ||
452 | else: | ||
453 | username = message.content[7:].replace('@', '').lower() | 535 | username = message.content[7:].replace('@', '').lower() |
454 | if username in data: | 536 | games_list = db_get_games(username) |
455 | games = ', '.join(get_game_names(data[username]['games_played'])) | 537 | if games_list: |
538 | games = ', '.join(games_list) | ||
456 | client.send_message(message.channel, 'I have seen {} playing: {}'.format(username, games)) | 539 | client.send_message(message.channel, 'I have seen {} playing: {}'.format(username, games)) |
457 | else: | 540 | else: |
458 | client.send_message(message.channel, 'I don\'t have any data on {} yet {}'.format(username, message.author.mention())) | 541 | client.send_message(message.channel, 'I don\'t have any data on {} yet {}'.format(username, message.author.mention())) |
459 | return | ||
460 | 542 | ||
461 | if message.content.startswith('!whoplayed'): | 543 | if message.content.startswith('!whoplayed'): |
462 | member_data = None | ||
463 | try: | ||
464 | json_data=open(member_status).read() | ||
465 | member_data = json.loads(json_data) | ||
466 | except ValueError: | ||
467 | pass | ||
468 | if not member_data: | ||
469 | client.send_message(message.channel, 'I am a bit confused right now.. maybe I need more data. {}!'.format(message.author.mention())) | ||
470 | else: | ||
471 | game_name = message.content[11:] | 544 | game_name = message.content[11:] |
472 | json_data=open(games_file).read() | 545 | member_list = db_get_whoplayed(game_name) |
473 | data = json.loads(json_data) | 546 | if not member_list: |
474 | game_id = 0 | 547 | client.send_message(message.channel, 'I don\'t have any data on {} yet {}'.format(byteify(game_name), message.author.mention())) |
475 | for game in data: | ||
476 | if game['name'].lower() == game_name.lower(): | ||
477 | game_id = game['id'] | ||
478 | #if game_id == 0: | ||
479 | # #client.send_message(message.channel, 'I don\'t have any data on {} yet {}'.format(game_name, message.author.mention())) | ||
480 | # #return | ||
481 | matched_usernames = [] | ||
482 | for username in member_data: | ||
483 | if 'games_played' in member_data[username]: | ||
484 | for id in member_data[username]['games_played']: | ||
485 | if id == game_name or (id == game_id and game_id != 0): | ||
486 | matched_usernames.append(username) | ||
487 | if len(matched_usernames) == 0: | ||
488 | client.send_message(message.channel, 'I don\'t have any data on {} yet {}'.format(game_name, message.author.mention())) | ||
489 | else: | 548 | else: |
490 | client.send_message(message.channel, 'I have seen {} playing: {}'.format(', '.join(matched_usernames), game_name)) | 549 | out_string = '' |
491 | 550 | for member in member_list: | |
551 | out_string += ' {} - {}\n'.format(byteify(member[1]), byteify(member[0])) | ||
552 | client.send_message(message.channel, 'Below is a list of people who have played {} and the number of times they have launched the game:'.format(byteify(game_name),)) | ||
553 | while len(out_string) > 0: | ||
554 | client.send_message(message.channel, out_string[:1900]) | ||
555 | out_string = out_string[1900:] | ||
492 | return | 556 | return |
557 | |||
558 | |||
493 | # !msg joe in 5 minutes YOU ARE A DICK | 559 | # !msg joe in 5 minutes YOU ARE A DICK |
494 | if message.content.startswith('!msg'): | 560 | if message.content.startswith('!msg'): |
495 | try: | 561 | try: |
... | @@ -530,6 +596,7 @@ Stuff: | ... | @@ -530,6 +596,7 @@ Stuff: |
530 | 596 | ||
531 | username = message_bits[1] | 597 | username = message_bits[1] |
532 | user_mention = '' | 598 | user_mention = '' |
599 | # TODO: have it look in the database. Do this AFTER on startup we add all users. | ||
533 | for member in client.get_all_members(): | 600 | for member in client.get_all_members(): |
534 | print("MEMBER: %s" % member) | 601 | print("MEMBER: %s" % member) |
535 | if username.lower() == member.name.lower(): | 602 | if username.lower() == member.name.lower(): |
... | @@ -542,16 +609,17 @@ Stuff: | ... | @@ -542,16 +609,17 @@ Stuff: |
542 | msg_text = byteify(' '.join(message_bits[msg_idx:])) | 609 | msg_text = byteify(' '.join(message_bits[msg_idx:])) |
543 | message = {'user_id': user_id, 'channel': channel.id, 'delivery_time': msg_datetime.strftime('%Y/%m/%d %H:%M:%S'), 'message': msg_text} | 610 | message = {'user_id': user_id, 'channel': channel.id, 'delivery_time': msg_datetime.strftime('%Y/%m/%d %H:%M:%S'), 'message': msg_text} |
544 | print("Message: %s" % message) | 611 | print("Message: %s" % message) |
545 | data[user_mention] = {} | 612 | db_add_message(msg_text, msg_datetime.strftime('%Y-%m-%d %H:%M:%S'), channel.id, author.mention(), user_mention, user_id) |
546 | data[user_mention][author.mention()] = message | 613 | # data[user_mention] = {} |
547 | jdata = json.dumps(data, ensure_ascii=False) | 614 | # data[user_mention][author.mention()] = message |
548 | print("Data: %s" % data) | 615 | # jdata = json.dumps(data, ensure_ascii=False) |
616 | # print("Data: %s" % data) | ||
549 | #test_ch = Object(channel.id) | 617 | #test_ch = Object(channel.id) |
550 | #client.send_message(test_ch, 'Test Message {}.'.format(author)) | 618 | #client.send_message(test_ch, 'Test Message {}.'.format(author)) |
551 | except Exception as e: | 619 | except Exception as e: |
552 | client.send_message(channel, 'Your shitty message has been rejected {}. {}'.format(author.name, e)) | 620 | client.send_message(channel, 'Your shitty message has been rejected {}. {}'.format(author.name, e)) |
553 | return | 621 | return |
554 | open(deliveries_file, 'wb+').write(jdata.encode('utf8')) | 622 | # open(deliveries_file, 'wb+').write(jdata.encode('utf8')) |
555 | if msg_datetime < datetime.datetime.now(): | 623 | if msg_datetime < datetime.datetime.now(): |
556 | client.send_message(channel, '{} your message will be delivered to {} as soon as they are available.'.format(author.name, user_mention)) | 624 | client.send_message(channel, '{} your message will be delivered to {} as soon as they are available.'.format(author.name, user_mention)) |
557 | else: | 625 | else: |
... | @@ -675,6 +743,7 @@ def on_ready(): | ... | @@ -675,6 +743,7 @@ def on_ready(): |
675 | print(client.user.name) | 743 | print(client.user.name) |
676 | print(client.user.id) | 744 | print(client.user.id) |
677 | print('------') | 745 | print('------') |
746 | check_msg_queue() | ||
678 | 747 | ||
679 | retries = 0 | 748 | retries = 0 |
680 | while retries < 1000: | 749 | while retries < 1000: |
... | @@ -683,7 +752,6 @@ while retries < 1000: | ... | @@ -683,7 +752,6 @@ while retries < 1000: |
683 | creds = json.loads(json_data) | 752 | creds = json.loads(json_data) |
684 | wolf = wolframalpha.Client(creds['wolframkey']) | 753 | wolf = wolframalpha.Client(creds['wolframkey']) |
685 | client.login(creds['username'], creds['password']) | 754 | client.login(creds['username'], creds['password']) |
686 | |||
687 | client.run() | 755 | client.run() |
688 | except KeyboardInterrupt: | 756 | except KeyboardInterrupt: |
689 | conn.close | 757 | conn.close | ... | ... |
1 | {"zan": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 09:25:10", "mention": "<@65178351664377856>", "prev_status": "online", "game_id": "Dragon's Dogma: Dark Arisen", "games_played": ["If My Heart Had Wings", "World of Warcraft", null, "XCOM: Enemy Unknown", "Go! Go! Nippon! ~My First Trip to Japan~", "Dragon's Dogma: Dark Arisen"], "afk_at": "2016/01/24 09:20:06", "id": "65178351664377856", "aliases": []}, "solidsteak": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 08:52:15", "mention": "<@62955839694053376>", "prev_status": "online", "game_id": "Rainbow Six Siege", "games_played": [248, null, 310, 533, 448, 715, 1, "Insurgency", "Rainbow Six Siege"], "afk_at": "2016/01/24 08:52:15", "id": "62955839694053376", "aliases": []}, "apple": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 09:34:37", "mention": "<@121822410096771072>", "prev_status": "idle", "games_played": [1, 6, null, "FINAL FANTASY XIV", "Borderlands 2"], "game_id": "FINAL FANTASY XIV", "afk_at": "2016/01/24 05:11:24", "id": "121822410096771072", "aliases": []}, "sheik": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/22 12:56:00", "mention": "<@48148712194576384>", "prev_status": "online", "game_id": "Guild Wars 2", "games_played": [283, null, 5, 11, 310, 249, 659, 308, 6, 260, 182, "Diablo 3", "Guild Wars 2", "Metal Gear Solid V: The Phantom Pain"], "afk_at": "2016/01/22 12:37:49", "id": "48148712194576384", "aliases": []}, "puncherboxer": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/04 04:11:44", "mention": "<@118544498996412416>", "prev_status": "online", "games_played": [], "game_id": null, "afk_at": "2015/12/04 03:48:11", "id": "118544498996412416"}, "rae": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 09:55:52", "mention": "<@48162082507456512>", "prev_status": "online", "game_id": "Dragon's Dogma: Dark Arisen", "games_played": [488, null, 141, "Dark Souls II", "Black Desert Online", "Dragon's Dogma: Dark Arisen"], "afk_at": "2016/01/24 09:55:52", "id": "48162082507456512", "aliases": []}, "marion": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/03 05:14:48", "prev_status": "online", "games_played": [1, null], "game_id": null, "afk_at": "2015/12/02 08:30:16"}, "shyrith": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/03 08:10:52", "prev_status": "online", "games_played": [1, 644, null], "game_id": null, "afk_at": "2015/12/02 21:54:35"}, "hiimapirate": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/12 05:08:57", "mention": "<@133758935009198080>", "prev_status": "online", "games_played": [], "game_id": null, "afk_at": "2015/12/20 11:34:43", "id": "133758935009198080", "aliases": []}, "az": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/23 06:17:41", "mention": "<@127330097949573121>", "prev_status": "online", "games_played": [], "game_id": null, "afk_at": "2015/12/19 06:10:40", "id": "127330097949573121", "aliases": []}, "yung_thirsty": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 08:36:17", "mention": "<@136368619423531008>", "prev_status": "online", "games_played": ["League of Legends", "Amnesia: The Dark Descent", "Clicker Heroes", "Crusader Kings II"], "game_id": "League of Legends", "afk_at": "2016/01/12 07:22:37", "id": "136368619423531008", "aliases": []}, "goshzilla": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 09:04:18", "mention": "<@47934670406422528>", "prev_status": "online", "games_played": [3, null, 6, 7, 777, "League of Legends", "Monster Hunter Online"], "game_id": "Monster Hunter Online", "afk_at": "2016/01/24 09:04:18", "id": "47934670406422528", "aliases": []}, "herbeh": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/11 10:46:35", "mention": "<@105392869782622208>", "prev_status": "online", "game_id": null, "games_played": [], "afk_at": "2016/01/11 08:46:57", "id": "105392869782622208", "aliases": []}, "eeri": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/15 06:31:49", "mention": "<@122023217371021313>", "prev_status": "online", "game_id": null, "games_played": [659, null], "afk_at": "2015/12/15 06:09:09", "id": "122023217371021313", "aliases": []}, "dick": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 10:00:54", "mention": "<@78767611436863488>", "prev_status": "online", "game_id": "Black Desert Online", "games_played": [372, null, 1, 488, "Dark Souls", "Metal Gear Solid V: The Phantom Pain", "Phantasy Star Online 2", "Black Desert Online"], "afk_at": "2016/01/24 10:00:54", "id": "78767611436863488", "aliases": []}, "arka": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 10:13:07", "mention": "<@121466618126532608>", "prev_status": "idle", "games_played": [1, null, 313, 488, "FINAL FANTASY XIV"], "game_id": "FINAL FANTASY XIV", "afk_at": "2016/01/24 09:57:47", "id": "121466618126532608", "aliases": []}, "wriggle": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/16 19:20:41", "mention": "<@80169354666192896>", "prev_status": "online", "games_played": [], "game_id": null, "afk_at": "2015/12/02 15:37:49", "id": "80169354666192896", "aliases": []}, "tim": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/04 10:25:19", "mention": "<@109145030354030592>", "prev_status": "online", "game_id": null, "games_played": [], "afk_at": "2015/12/04 07:08:23", "id": "109145030354030592"}, "charisma": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 07:23:41", "mention": "<@65187139276513280>", "prev_status": "online", "game_id": "Dragon's Dogma: Dark Arisen", "games_played": [313, null, 807, 471, 671, 728, 0, "Sony Playstation Emulator", "Black Desert Online", "Dragon's Dogma: Dark Arisen"], "afk_at": "2016/01/24 07:23:41", "id": "65187139276513280", "aliases": []}, "mate": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/04 09:11:30", "mention": "<@109145154044071936>", "prev_status": "online", "game_id": null, "games_played": [], "afk_at": "2015/12/04 05:06:58", "id": "109145154044071936"}, "sig": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/23 13:11:50", "mention": "<@104055037243707392>", "prev_status": "online", "games_played": [8, null, 7, 466, 588, 15, 6, 13, 165, 669, 101, "Diablo 3", "Tabletop Simulator", "DOTA 2", "Crusader Kings II"], "game_id": "DOTA 2", "afk_at": "2016/01/23 05:03:03", "id": "104055037243707392", "aliases": []}, "bunta": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 05:09:39", "mention": "<@122520378089275395>", "prev_status": "online", "game_id": null, "games_played": [488, null], "afk_at": "2016/01/24 05:09:39", "id": "122520378089275395", "aliases": []}, "mr. nelson": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/14 13:35:09", "mention": "<@103311664748707840>", "prev_status": "online", "game_id": null, "games_played": [], "afk_at": "2015/12/14 10:25:27", "id": "103311664748707840", "aliases": []}, "草 goshzilla": {"status": "online", "is_afk": false, "status_change_at": "2016/01/15 15:28:19", "mention": "<@47934670406422528>", "prev_status": "offline", "game_id": null, "games_played": [], "afk_at": "2016/01/15 08:23:14", "id": "47934670406422528", "aliases": []}, "skeletonhorn": {"status": "online", "is_afk": false, "status_change_at": "2015/12/03 00:36:39", "prev_status": "offline", "games_played": [], "game_id": null, "afk_at": "2015/12/03 00:36:39"}, "yoltan": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/08 23:38:09", "mention": "<@122369674808786948>", "prev_status": "online", "games_played": [238, null, 307], "game_id": null, "afk_at": "2015/12/04 16:14:00", "id": "122369674808786948", "aliases": []}, "rui": {"status": "online", "mention": "<@63649222993391616>", "is_afk": false, "games_played": [174, null, 660, 724, 488, 149, 780, 301, 438, 140, 680, "Grand Theft Auto V", "Dragon's Dogma: Dark Arisen"], "game_id": "Dragon's Dogma: Dark Arisen", "afk_at": "2016/01/24 09:55:44", "status_change_at": "2016/01/24 10:04:13", "id": "63649222993391616", "prev_status": "idle", "aliases": []}, "adol": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 04:45:52", "mention": "<@122079633796497409>", "prev_status": "online", "game_id": "Clicker Heroes", "games_played": [550, null, 1, "Black Desert Online", "Clicker Heroes"], "afk_at": "2016/01/24 03:10:24", "id": "122079633796497409", "aliases": []}, "xorfos": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 06:54:12", "mention": "<@121019458700443650>", "prev_status": "online", "game_id": "Cook, Serve, Delicious!", "games_played": [430, null, 550, 140, "Dwarf Fortress", "Tales of Zestiria", "Cook, Serve, Delicious!"], "afk_at": "2016/01/24 06:54:12", "id": "121019458700443650", "aliases": []}, "roris": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 08:10:56", "mention": "<@80876422352076800>", "prev_status": "online", "game_id": "Dragon's Dogma: Dark Arisen", "games_played": [1, null, 0, 658, 345, 724, 471, 269, 307, "Grandia 2", "Black Desert Online", "Dragon's Dogma: Dark Arisen"], "afk_at": "2016/01/24 00:50:04", "id": "80876422352076800", "aliases": []}, "projectaria": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 10:06:36", "mention": "<@48146724769763328>", "prev_status": "idle", "game_id": "Nintendo Emulator", "games_played": [1, null, "Nintendo Emulator"], "afk_at": "2016/01/24 09:13:15", "id": "48146724769763328", "aliases": []}, "moss": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 10:15:27", "mention": "<@48168872238387200>", "prev_status": "online", "games_played": [0, null, 1, 715, 127, 206, 440], "game_id": null, "afk_at": "2016/01/20 23:28:15", "id": "48168872238387200", "aliases": []}, "master of moisture": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/20 10:57:33", "mention": "<@112340697771765760>", "prev_status": "idle", "game_id": null, "games_played": [], "afk_at": "2015/12/20 10:52:58", "id": "112340697771765760", "aliases": []}, "hellsbreath:skull:": {"status": "online", "is_afk": false, "status_change_at": "2015/12/10 15:13:36", "mention": "<@78767557628133376>", "prev_status": "offline", "games_played": [], "game_id": null, "afk_at": "2015/12/10 15:13:36", "id": "78767557628133376", "aliases": []}, "hellsbreath :skull:": {"status": "online", "is_afk": false, "status_change_at": "2015/12/10 15:13:50", "mention": "<@78767557628133376>", "prev_status": "offline", "game_id": null, "games_played": [], "afk_at": "2015/12/10 15:13:50", "id": "78767557628133376", "aliases": []}, "yobi": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 10:14:51", "mention": "<@65180855919714304>", "prev_status": "online", "game_id": null, "games_played": [3, null, 680, 379, "Unity", "World of Warcraft"], "afk_at": "2016/01/24 10:14:51", "id": "65180855919714304", "aliases": []}, "salt": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 07:12:09", "mention": "<@48140539459010560>", "prev_status": "idle", "games_played": [466, 8, null, 680, 588, 15, 512, 260, "Hearthstone", "Tabletop Simulator", "Crusader Kings II"], "game_id": "Hearthstone", "afk_at": "2016/01/24 06:42:59", "id": "48140539459010560", "aliases": []}, "study": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 10:14:35", "mention": "<@121821978222002178>", "prev_status": "idle", "games_played": ["FINAL FANTASY XIV", "Rocket League", "Dragon's Dogma: Dark Arisen"], "game_id": "Dragon's Dogma: Dark Arisen", "afk_at": "2016/01/24 10:14:15", "id": "121821978222002178", "aliases": []}, "草 goshzilla 一角": {"status": "online", "is_afk": false, "status_change_at": "2016/01/17 18:31:46", "mention": "<@47934670406422528>", "prev_status": "idle", "game_id": "League of Legends", "games_played": ["League of Legends"], "afk_at": "2016/01/17 18:27:26", "id": "47934670406422528", "aliases": []}, "grey": {"status": "online", "is_afk": false, "status_change_at": "2016/01/23 03:54:03", "mention": "<@48120346410221568>", "prev_status": "offline", "games_played": [550, null, 1, 208, 283, 318, "Counter-Strike: Global Offensive", "FINAL FANTASY XIV", "Skyforge", "Dark Souls II", "Crypt of the NecroDancer", "", "Rocket League", "Dragon's Dogma: Dark Arisen"], "game_id": "Dark Souls II", "afk_at": "2016/01/20 10:14:28", "id": "48120346410221568", "aliases": []}, "hellsbreath": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 10:08:27", "mention": "<@78767557628133376>", "prev_status": "offline", "games_played": [326, null, 660, 680, 566, 441, 363, 488, 246, "The Last Remnant", "Phantasy Star Online 2", "FINAL FANTASY XI", "Rainbow Six Siege", "Tales of Zestiria", "SolForge"], "game_id": "SolForge", "afk_at": "2016/01/24 09:04:01", "id": "78767557628133376", "aliases": ["Barry", "Ben Killin", "Hellsbreath", "Barry", "Ben Killin"]}, "green": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 06:54:32", "mention": "<@63098846506397696>", "prev_status": "idle", "games_played": [4, null, 3, 11, "League of Legends"], "game_id": "League of Legends", "afk_at": "2016/01/24 06:50:07", "id": "63098846506397696", "aliases": []}, "azia": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 01:01:33", "mention": "<@121404665727418368>", "prev_status": "offline", "games_played": ["Dragon's Dogma: Dark Arisen"], "game_id": "Dragon's Dogma: Dark Arisen", "afk_at": "2016/01/23 06:32:51", "id": "121404665727418368", "aliases": []}, "scoops": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 01:44:34", "mention": "<@65211875771559936>", "prev_status": "online", "games_played": [347, null, 0, 644, 308, 15, 3, 306, 351, "Counter-Strike: Global Offensive", "Rocket League"], "game_id": null, "afk_at": "2016/01/23 19:28:16", "id": "65211875771559936", "aliases": []}, "richter": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 06:50:08", "mention": "<@49237234515181568>", "prev_status": "online", "games_played": [488, null, 183, 11], "game_id": null, "afk_at": "2016/01/24 05:30:10", "id": "49237234515181568", "aliases": []}, "cae": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 07:15:06", "mention": "<@65178683714830336>", "prev_status": "online", "game_id": null, "games_played": [335, null, 215, 112, 274, 443, "Undertale"], "afk_at": "2016/01/24 07:15:06", "id": "65178683714830336", "aliases": []}} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | {"zan": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 23:39:00", "mention": "<@65178351664377856>", "prev_status": "idle", "games_played": ["If My Heart Had Wings", "World of Warcraft", null, "XCOM: Enemy Unknown", "Go! Go! Nippon! ~My First Trip to Japan~", "Dragon's Dogma: Dark Arisen"], "game_id": "Dragon's Dogma: Dark Arisen", "afk_at": "2016/01/24 23:38:52", "id": "65178351664377856", "aliases": []}, "solidsteak": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 23:56:33", "mention": "<@62955839694053376>", "prev_status": "idle", "games_played": [248, null, 310, 533, 448, 715, 1, "Insurgency", "Rainbow Six Siege"], "game_id": null, "afk_at": "2016/01/24 23:05:50", "id": "62955839694053376", "aliases": []}, "apple": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 22:57:47", "mention": "<@121822410096771072>", "prev_status": "online", "games_played": [1, 6, null, "FINAL FANTASY XIV", "Borderlands 2"], "game_id": "FINAL FANTASY XIV", "afk_at": "2016/01/24 22:57:47", "id": "121822410096771072", "aliases": []}, "sheik": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 23:09:43", "mention": "<@48148712194576384>", "prev_status": "online", "games_played": [283, null, 5, 11, 310, 249, 659, 308, 6, 260, 182, "Diablo 3", "Guild Wars 2", "Metal Gear Solid V: The Phantom Pain", "Dragon's Dogma: Dark Arisen"], "game_id": null, "afk_at": "2016/01/24 23:09:43", "id": "48148712194576384", "aliases": []}, "puncherboxer": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/04 04:11:44", "mention": "<@118544498996412416>", "prev_status": "online", "games_played": [], "game_id": null, "afk_at": "2015/12/04 03:48:11", "id": "118544498996412416"}, "rae": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 23:53:05", "mention": "<@48162082507456512>", "prev_status": "idle", "games_played": [488, null, 141, "Dark Souls II", "Black Desert Online", "Dragon's Dogma: Dark Arisen"], "game_id": "Dragon's Dogma: Dark Arisen", "afk_at": "2016/01/24 23:52:05", "id": "48162082507456512", "aliases": []}, "marion": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/03 05:14:48", "prev_status": "online", "games_played": [1, null], "game_id": null, "afk_at": "2015/12/02 08:30:16"}, "shyrith": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/03 08:10:52", "prev_status": "online", "games_played": [1, 644, null], "game_id": null, "afk_at": "2015/12/02 21:54:35"}, "hiimapirate": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/12 05:08:57", "mention": "<@133758935009198080>", "prev_status": "online", "games_played": [], "game_id": null, "afk_at": "2015/12/20 11:34:43", "id": "133758935009198080", "aliases": []}, "az": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/23 06:17:41", "mention": "<@127330097949573121>", "prev_status": "online", "games_played": [], "game_id": null, "afk_at": "2015/12/19 06:10:40", "id": "127330097949573121", "aliases": []}, "yung_thirsty": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 08:36:17", "mention": "<@136368619423531008>", "prev_status": "online", "games_played": ["League of Legends", "Amnesia: The Dark Descent", "Clicker Heroes", "Crusader Kings II"], "game_id": "League of Legends", "afk_at": "2016/01/12 07:22:37", "id": "136368619423531008", "aliases": []}, "goshzilla": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 22:31:01", "mention": "<@47934670406422528>", "prev_status": "idle", "game_id": "Monster Hunter Online", "games_played": [3, null, 6, 7, 777, "League of Legends", "Monster Hunter Online"], "afk_at": "2016/01/24 22:08:02", "id": "47934670406422528", "aliases": []}, "herbeh": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/11 10:46:35", "mention": "<@105392869782622208>", "prev_status": "online", "game_id": null, "games_played": [], "afk_at": "2016/01/11 08:46:57", "id": "105392869782622208", "aliases": []}, "eeri": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/15 06:31:49", "mention": "<@122023217371021313>", "prev_status": "online", "game_id": null, "games_played": [659, null], "afk_at": "2015/12/15 06:09:09", "id": "122023217371021313", "aliases": []}, "dick": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 22:39:52", "mention": "<@78767611436863488>", "prev_status": "online", "games_played": [372, null, 1, 488, "Dark Souls", "Metal Gear Solid V: The Phantom Pain", "Phantasy Star Online 2", "Black Desert Online"], "game_id": null, "afk_at": "2016/01/24 22:39:52", "id": "78767611436863488", "aliases": []}, "arka": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 23:44:00", "mention": "<@121466618126532608>", "prev_status": "offline", "games_played": [1, null, 313, 488, "FINAL FANTASY XIV"], "game_id": null, "afk_at": "2016/01/24 23:03:26", "id": "121466618126532608", "aliases": []}, "wriggle": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/16 19:20:41", "mention": "<@80169354666192896>", "prev_status": "online", "games_played": [], "game_id": null, "afk_at": "2015/12/02 15:37:49", "id": "80169354666192896", "aliases": []}, "tim": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/04 10:25:19", "mention": "<@109145030354030592>", "prev_status": "online", "game_id": null, "games_played": [], "afk_at": "2015/12/04 07:08:23", "id": "109145030354030592"}, "charisma": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 22:42:31", "mention": "<@65187139276513280>", "prev_status": "idle", "game_id": "Dragon's Dogma: Dark Arisen", "games_played": [313, null, 807, 471, 671, 728, 0, "Sony Playstation Emulator", "Black Desert Online", "Dragon's Dogma: Dark Arisen"], "afk_at": "2016/01/24 22:42:11", "id": "65187139276513280", "aliases": []}, "mate": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/04 09:11:30", "mention": "<@109145154044071936>", "prev_status": "online", "game_id": null, "games_played": [], "afk_at": "2015/12/04 05:06:58", "id": "109145154044071936"}, "sig": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/23 13:11:50", "mention": "<@104055037243707392>", "prev_status": "online", "games_played": [8, null, 7, 466, 588, 15, 6, 13, 165, 669, 101, "Diablo 3", "Tabletop Simulator", "DOTA 2", "Crusader Kings II"], "game_id": "DOTA 2", "afk_at": "2016/01/23 05:03:03", "id": "104055037243707392", "aliases": []}, "bunta": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 22:24:40", "mention": "<@122520378089275395>", "prev_status": "online", "game_id": null, "games_played": [488, null], "afk_at": "2016/01/24 22:24:40", "id": "122520378089275395", "aliases": []}, "mr. nelson": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/14 13:35:09", "mention": "<@103311664748707840>", "prev_status": "online", "game_id": null, "games_played": [], "afk_at": "2015/12/14 10:25:27", "id": "103311664748707840", "aliases": []}, "草 goshzilla": {"status": "online", "is_afk": false, "status_change_at": "2016/01/15 15:28:19", "mention": "<@47934670406422528>", "prev_status": "offline", "game_id": null, "games_played": [], "afk_at": "2016/01/15 08:23:14", "id": "47934670406422528", "aliases": []}, "skeletonhorn": {"status": "online", "is_afk": false, "status_change_at": "2015/12/03 00:36:39", "prev_status": "offline", "games_played": [], "game_id": null, "afk_at": "2015/12/03 00:36:39"}, "yoltan": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/08 23:38:09", "mention": "<@122369674808786948>", "prev_status": "online", "games_played": [238, null, 307], "game_id": null, "afk_at": "2015/12/04 16:14:00", "id": "122369674808786948", "aliases": []}, "rui": {"status": "offline", "is_afk": false, "status_change_at": "2016/01/24 23:35:21", "mention": "<@63649222993391616>", "prev_status": "online", "games_played": [174, null, 660, 724, 488, 149, 780, 301, 438, 140, 680, "Grand Theft Auto V", "Dragon's Dogma: Dark Arisen"], "game_id": "Grand Theft Auto V", "afk_at": "2016/01/24 23:17:25", "id": "63649222993391616", "aliases": []}, "adol": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 15:58:19", "mention": "<@122079633796497409>", "prev_status": "idle", "games_played": [550, null, 1, "Black Desert Online", "Clicker Heroes"], "game_id": "Clicker Heroes", "afk_at": "2016/01/24 15:57:49", "id": "122079633796497409", "aliases": []}, "xorfos": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 22:35:29", "mention": "<@121019458700443650>", "prev_status": "online", "game_id": null, "games_played": [430, null, 550, 140, "Dwarf Fortress", "Tales of Zestiria", "Cook, Serve, Delicious!"], "afk_at": "2016/01/24 22:35:29", "id": "121019458700443650", "aliases": []}, "roris": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 22:58:35", "mention": "<@80876422352076800>", "prev_status": "online", "game_id": "Dragon's Dogma: Dark Arisen", "games_played": [1, null, 0, 658, 345, 724, 471, 269, 307, "Grandia 2", "Black Desert Online", "Dragon's Dogma: Dark Arisen"], "afk_at": "2016/01/24 22:58:35", "id": "80876422352076800", "aliases": []}, "projectaria": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 20:40:15", "mention": "<@48146724769763328>", "prev_status": "online", "game_id": null, "games_played": [1, null, "Nintendo Emulator"], "afk_at": "2016/01/24 20:40:15", "id": "48146724769763328", "aliases": []}, "moss": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 22:43:58", "mention": "<@48168872238387200>", "prev_status": "idle", "games_played": [0, null, 1, 715, 127, 206, 440], "game_id": null, "afk_at": "2016/01/24 22:35:08", "id": "48168872238387200", "aliases": []}, "master of moisture": {"status": "offline", "is_afk": false, "status_change_at": "2015/12/20 10:57:33", "mention": "<@112340697771765760>", "prev_status": "idle", "game_id": null, "games_played": [], "afk_at": "2015/12/20 10:52:58", "id": "112340697771765760", "aliases": []}, "hellsbreath:skull:": {"status": "online", "is_afk": false, "status_change_at": "2015/12/10 15:13:36", "mention": "<@78767557628133376>", "prev_status": "offline", "games_played": [], "game_id": null, "afk_at": "2015/12/10 15:13:36", "id": "78767557628133376", "aliases": []}, "hellsbreath :skull:": {"status": "online", "is_afk": false, "status_change_at": "2015/12/10 15:13:50", "mention": "<@78767557628133376>", "prev_status": "offline", "game_id": null, "games_played": [], "afk_at": "2015/12/10 15:13:50", "id": "78767557628133376", "aliases": []}, "yobi": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 20:05:45", "mention": "<@65180855919714304>", "prev_status": "idle", "games_played": [3, null, 680, 379, "Unity", "World of Warcraft"], "game_id": null, "afk_at": "2016/01/24 19:55:05", "id": "65180855919714304", "aliases": []}, "salt": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 21:52:01", "mention": "<@48140539459010560>", "prev_status": "offline", "game_id": null, "games_played": [466, 8, null, 680, 588, 15, 512, 260, "Hearthstone", "Tabletop Simulator", "Crusader Kings II"], "afk_at": "2016/01/24 11:15:21", "id": "48140539459010560", "aliases": []}, "study": {"status": "online", "mention": "<@121821978222002178>", "is_afk": false, "games_played": ["FINAL FANTASY XIV", "Rocket League", "Dragon's Dogma: Dark Arisen", null], "game_id": "Dragon's Dogma: Dark Arisen", "afk_at": "2016/01/24 10:24:35", "status_change_at": "2016/01/24 23:41:56", "id": "121821978222002178", "prev_status": "offline", "aliases": []}, "草 goshzilla 一角": {"status": "online", "is_afk": false, "status_change_at": "2016/01/17 18:31:46", "mention": "<@47934670406422528>", "prev_status": "idle", "game_id": "League of Legends", "games_played": ["League of Legends"], "afk_at": "2016/01/17 18:27:26", "id": "47934670406422528", "aliases": []}, "grey": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 19:25:55", "mention": "<@48120346410221568>", "prev_status": "offline", "games_played": [550, null, 1, 208, 283, 318, "Counter-Strike: Global Offensive", "FINAL FANTASY XIV", "Skyforge", "Dark Souls II", "Crypt of the NecroDancer", "", "Rocket League", "Dragon's Dogma: Dark Arisen"], "game_id": "Dragon's Dogma: Dark Arisen", "afk_at": "2016/01/24 15:28:16", "id": "48120346410221568", "aliases": []}, "hellsbreath": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 23:32:44", "mention": "<@78767557628133376>", "prev_status": "offline", "games_played": [326, null, 660, 680, 566, 441, 363, 488, 246, "The Last Remnant", "Phantasy Star Online 2", "FINAL FANTASY XI", "Rainbow Six Siege", "Tales of Zestiria", "SolForge", "Fallout 4", "Wolfenstein.The.New.Order", "King's Quest"], "game_id": null, "afk_at": "2016/01/24 19:58:40", "id": "78767557628133376", "aliases": ["Barry", "Ben Killin", "Hellsbreath", "Barry", "Ben Killin"]}, "green": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 23:04:39", "mention": "<@63098846506397696>", "prev_status": "offline", "game_id": null, "games_played": [4, null, 3, 11, "League of Legends"], "afk_at": "2016/01/24 06:50:07", "id": "63098846506397696", "aliases": []}, "azia": {"status": "idle", "is_afk": true, "status_change_at": "2016/01/24 18:56:35", "mention": "<@121404665727418368>", "prev_status": "online", "games_played": ["Dragon's Dogma: Dark Arisen", null], "game_id": null, "afk_at": "2016/01/24 18:56:35", "id": "121404665727418368", "aliases": []}, "scoops": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 18:58:15", "mention": "<@65211875771559936>", "prev_status": "offline", "games_played": [347, null, 0, 644, 308, 15, 3, 306, 351, "Counter-Strike: Global Offensive", "Rocket League"], "game_id": null, "afk_at": "2016/01/23 19:28:16", "id": "65211875771559936", "aliases": []}, "richter": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 22:41:52", "mention": "<@49237234515181568>", "prev_status": "idle", "game_id": null, "games_played": [488, null, 183, 11], "afk_at": "2016/01/24 22:36:41", "id": "49237234515181568", "aliases": []}, "cae": {"status": "online", "is_afk": false, "status_change_at": "2016/01/24 21:27:13", "mention": "<@65178683714830336>", "prev_status": "idle", "games_played": [335, null, 215, 112, 274, 443, "Undertale"], "game_id": null, "afk_at": "2016/01/24 21:13:13", "id": "65178683714830336", "aliases": []}} | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment