Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F145135
game.lua
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
13 KB
Referenced Files
None
Subscribers
None
game.lua
View Options
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local
game
=
{}
local
mattata
=
require
(
'mattata'
)
local
socket
=
require
(
'socket'
)
local
json
=
require
(
'dkjson'
)
local
redis
=
require
(
'libs.redis'
)
function
game
:
init
()
game
.
commands
=
mattata
.
commands
(
self
.
info
.
username
):
command
(
'game'
):
command
(
'tictactoe'
).
table
game
.
help
=
'/game - View your current game statistics. Alias: /tictactoe.'
end
function
game
.
get_stats
(
user_id
,
language
)
local
user_won
=
redis
:
get
(
'games_won:'
..
user_id
)
if
not
user_won
then
user_won
=
0
end
local
user_lost
=
redis
:
get
(
'games_lost:'
..
user_id
)
if
not
user_lost
then
user_lost
=
0
end
local
balance
=
redis
:
get
(
'balance:'
..
user_id
)
if
not
balance
then
balance
=
0
end
return
string.format
(
language
[
'game'
][
'1'
],
user_won
,
user_lost
,
balance
)
end
function
game
.
set_stats
(
user_id
,
set_type
)
local
user_won
=
redis
:
get
(
'games_won:'
..
user_id
)
if
not
user_won
then
user_won
=
0
end
local
user_lost
=
redis
:
get
(
'games_lost:'
..
user_id
)
if
not
user_lost
then
user_lost
=
0
end
local
balance
=
redis
:
get
(
'balance:'
..
user_id
)
if
not
balance
then
balance
=
0
end
if
set_type
==
'won'
then
user_won
=
tonumber
(
user_won
)
+
1
redis
:
set
(
'games_won:'
..
user_id
,
user_won
)
balance
=
tonumber
(
balance
)
+
100
redis
:
set
(
'balance:'
..
user_id
,
balance
)
elseif
set_type
==
'lost'
then
user_lost
=
tonumber
(
user_lost
)
+
1
redis
:
set
(
'games_lost:'
..
user_id
,
user_lost
)
balance
=
tonumber
(
balance
)
-
50
redis
:
set
(
'balance:'
..
user_id
,
balance
)
end
end
function
game
.
get_keyboard
(
session_id
,
join_game
,
language
)
join_game
=
join_game
or
false
local
g
=
redis
:
get
(
'games:noughts_and_crosses:'
..
session_id
)
if
not
g
then
return
false
end
g
=
json
.
decode
(
g
)
local
keyboard
=
{
[
'inline_keyboard'
]
=
{{{
[
'text'
]
=
g
.
moves
.
a1
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':a1'
},
{
[
'text'
]
=
g
.
moves
.
a2
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':a2'
},
{
[
'text'
]
=
g
.
moves
.
a3
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':a3'
}},
{{
[
'text'
]
=
g
.
moves
.
b1
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':b1'
},
{
[
'text'
]
=
g
.
moves
.
b2
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':b2'
},
{
[
'text'
]
=
g
.
moves
.
b3
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':b3'
}},
{{
[
'text'
]
=
g
.
moves
.
c1
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':c1'
},
{
[
'text'
]
=
g
.
moves
.
c2
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':c2'
},
{
[
'text'
]
=
g
.
moves
.
c3
,
[
'callback_data'
]
=
'game:'
..
session_id
..
':c3'
}}}}
if
join_game
then
table.insert
(
keyboard
.
inline_keyboard
,
{{
[
'text'
]
=
language
[
'game'
][
'2'
],
[
'callback_data'
]
=
'game:'
..
session_id
..
':join_game'
}})
end
return
keyboard
end
function
game
.
on_callback_query
(
_
,
callback_query
,
_
,
_
,
language
)
local
session_id
=
callback_query
.
data
:
match
(
'^(%d+)%:'
)
local
g
=
redis
:
get
(
'games:noughts_and_crosses:'
..
session_id
)
if
not
g
or
not
callback_query
.
inline_message_id
then
return
end
g
=
json
.
decode
(
g
)
if
g
.
is_over
==
true
then
return
mattata
.
answer_callback_query
(
callback_query
.
id
,
language
[
'game'
][
'3'
])
elseif
g
.
has_opponent
==
true
and
g
.
is_over
==
false
then
if
callback_query
.
from
.
id
==
g
.
opponent
.
id
then
if
g
.
opponent
.
is_go
==
false
then
return
mattata
.
answer_callback_query
(
callback_query
.
id
,
language
[
'game'
][
'4'
])
end
elseif
callback_query
.
from
.
id
==
g
.
player
.
id
then
if
g
.
player
.
is_go
==
false
then
return
mattata
.
answer_callback_query
(
callback_query
.
id
,
language
[
'game'
][
'4'
])
end
end
if
not
callback_query
.
data
:
match
(
'^%d+%:%a%d$'
)
then
return
end
local
pos
=
callback_query
.
data
:
match
(
'^%d+%:(%a%d)$'
)
local
move
=
false
if
callback_query
.
from
.
id
~=
g
.
opponent
.
id
and
callback_query
.
from
.
id
~=
g
.
player
.
id
then
return
mattata
.
answer_callback_query
(
callback_query
.
id
,
language
[
'game'
][
'5'
])
elseif
callback_query
.
from
.
id
==
g
.
player
.
id
then
g
.
player
.
is_go
=
false
g
.
opponent
.
is_go
=
true
move
=
g
.
player
.
move
elseif
callback_query
.
from
.
id
==
g
.
opponent
.
id
then
g
.
player
.
is_go
=
true
g
.
opponent
.
is_go
=
false
move
=
g
.
opponent
.
move
end
if
not
move
then
return
elseif
g
.
moves
[
pos
]
~=
utf8.char
(
65039
)
then
return
mattata
.
answer_callback_query
(
callback_query
.
id
,
language
[
'game'
][
'6'
])
end
g
.
moves
[
pos
]
=
move
if
g
.
moves
.
a1
==
g
.
moves
.
a2
and
g
.
moves
.
a2
==
g
.
moves
.
a3
and
g
.
moves
.
a2
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
a1
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
b1
==
g
.
moves
.
b2
and
g
.
moves
.
b2
==
g
.
moves
.
b3
and
g
.
moves
.
b2
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
b1
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
c1
==
g
.
moves
.
c2
and
g
.
moves
.
c2
==
g
.
moves
.
c3
and
g
.
moves
.
c2
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
c1
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
a1
==
g
.
moves
.
b2
and
g
.
moves
.
b2
==
g
.
moves
.
c3
and
g
.
moves
.
b2
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
a1
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
a3
==
g
.
moves
.
b2
and
g
.
moves
.
b2
==
g
.
moves
.
c1
and
g
.
moves
.
b2
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
a3
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
a2
==
g
.
moves
.
b2
and
g
.
moves
.
b2
==
g
.
moves
.
c2
and
g
.
moves
.
b2
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
a2
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
b1
==
g
.
moves
.
b2
and
g
.
moves
.
b2
==
g
.
moves
.
b3
and
g
.
moves
.
b2
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
b1
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
a1
==
g
.
moves
.
b1
and
g
.
moves
.
b1
==
g
.
moves
.
c1
and
g
.
moves
.
b1
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
a1
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
a2
==
g
.
moves
.
b2
and
g
.
moves
.
b2
==
g
.
moves
.
c2
and
g
.
moves
.
b2
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
a2
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
a3
==
g
.
moves
.
b3
and
g
.
moves
.
b3
==
g
.
moves
.
c3
and
g
.
moves
.
b3
~=
utf8.char
(
65039
)
then
g
.
winner
=
g
.
opponent
.
id
g
.
loser
=
g
.
player
.
id
if
g
.
player
.
move
==
g
.
moves
.
a3
then
g
.
winner
=
g
.
player
.
id
g
.
loser
=
g
.
opponent
.
id
end
g
.
is_over
=
true
g
.
was_won
=
true
elseif
g
.
moves
.
a1
~=
utf8.char
(
65039
)
and
g
.
moves
.
a2
~=
utf8.char
(
65039
)
and
g
.
moves
.
a3
~=
utf8.char
(
65039
)
and
g
.
moves
.
b1
~=
utf8.char
(
65039
)
and
g
.
moves
.
b2
~=
utf8.char
(
65039
)
and
g
.
moves
.
b3
~=
utf8.char
(
65039
)
and
g
.
moves
.
c1
~=
utf8.char
(
65039
)
and
g
.
moves
.
c2
~=
utf8.char
(
65039
)
and
g
.
moves
.
c3
~=
utf8.char
(
65039
)
then
g
.
is_over
=
true
end
redis
:
set
(
'games:noughts_and_crosses:'
..
session_id
,
json
.
encode
(
g
))
elseif
callback_query
.
data
:
match
(
'^%d+%:join%_game$'
)
then
if
callback_query
.
from
.
id
==
g
.
player
.
id
then
return
mattata
.
answer_callback_query
(
callback_query
.
id
,
language
[
'game'
][
'7'
])
end
g
.
has_opponent
=
true
g
.
opponent
.
id
=
callback_query
.
from
.
id
redis
:
set
(
'games:noughts_and_crosses:'
..
session_id
,
json
.
encode
(
g
))
else
return
mattata
.
answer_callback_query
(
callback_query
.
id
,
language
[
'game'
][
'8'
])
end
local
keyboard
=
game
.
get_keyboard
(
session_id
)
if
not
keyboard
then
return
end
local
currently
=
g
.
player
.
id
if
g
.
player
.
is_go
==
false
then
currently
=
g
.
opponent
.
id
end
local
output
=
string.format
(
language
[
'game'
][
'9'
],
mattata
.
get_linked_name
(
g
.
player
.
id
),
g
.
player
.
move
,
mattata
.
get_linked_name
(
g
.
opponent
.
id
),
g
.
opponent
.
move
,
mattata
.
get_linked_name
(
currently
)
)
if
g
.
is_over
==
true
then
if
g
.
was_won
==
true
then
game
.
set_stats
(
g
.
winner
,
'won'
)
game
.
set_stats
(
g
.
loser
,
'lost'
)
output
=
string.format
(
language
[
'game'
][
'10'
],
mattata
.
get_linked_name
(
g
.
winner
),
mattata
.
get_linked_name
(
g
.
loser
)
)
else
output
=
string.format
(
language
[
'game'
][
'11'
],
mattata
.
get_linked_name
(
g
.
player
.
id
),
mattata
.
get_linked_name
(
g
.
opponent
.
id
)
)
end
end
return
mattata
.
edit_message_text
(
nil
,
nil
,
output
,
'html'
,
true
,
keyboard
,
callback_query
.
inline_message_id
)
end
function
game
.
on_inline_query
(
_
,
inline_query
,
_
,
language
)
local
session_id
=
tostring
(
socket
.
gettime
()):
gsub
(
'%D'
,
''
)
local
rnd
=
math.random
(
10
)
local
g
=
{
[
'is_over'
]
=
false
,
[
'was_won'
]
=
false
,
[
'has_opponent'
]
=
false
,
[
'player'
]
=
{
[
'id'
]
=
inline_query
.
from
.
id
,
[
'move'
]
=
utf8.char
(
10060
),
[
'is_go'
]
=
true
},
[
'opponent'
]
=
{
[
'id'
]
=
utf8.char
(
65039
),
[
'move'
]
=
utf8.char
(
11093
),
[
'is_go'
]
=
false
},
[
'moves'
]
=
{
[
'a1'
]
=
utf8.char
(
65039
),
[
'a2'
]
=
utf8.char
(
65039
),
[
'a3'
]
=
utf8.char
(
65039
),
[
'b1'
]
=
utf8.char
(
65039
),
[
'b2'
]
=
utf8.char
(
65039
),
[
'b3'
]
=
utf8.char
(
65039
),
[
'c1'
]
=
utf8.char
(
65039
),
[
'c2'
]
=
utf8.char
(
65039
),
[
'c3'
]
=
utf8.char
(
65039
)
}
}
if
math.random
(
2
)
==
1
then
g
.
player
.
is_go
=
false
g
.
opponent
.
is_go
=
true
end
if
rnd
==
2
then
g
.
player
.
move
=
utf8.char
(
128514
)
g
.
opponent
.
move
=
utf8.char
(
128561
)
elseif
rnd
==
3
then
g
.
player
.
move
=
utf8.char
(
127814
)
g
.
opponent
.
move
=
utf8.char
(
127825
)
elseif
rnd
==
4
then
g
.
player
.
move
=
utf8.char
(
10084
)
g
.
opponent
.
move
=
utf8.char
(
128420
)
elseif
rnd
==
5
then
g
.
player
.
move
=
utf8.char
(
128584
)
g
.
opponent
.
move
=
utf8.char
(
128585
)
elseif
rnd
==
6
then
g
.
player
.
move
=
utf8.char
(
127770
)
g
.
opponent
.
move
=
utf8.char
(
127773
)
elseif
rnd
==
7
then
g
.
player
.
move
=
utf8.char
(
128293
)
g
.
opponent
.
move
=
utf8.char
(
10052
)
elseif
rnd
==
8
then
g
.
player
.
move
=
utf8.char
(
127823
)
g
.
opponent
.
move
=
utf8.char
(
127821
)
elseif
rnd
==
9
then
g
.
player
.
move
=
'Ayy'
g
.
opponent
.
move
=
'Lmao'
elseif
rnd
==
10
then
g
.
player
.
move
=
utf8.char
(
128166
)
g
.
opponent
.
move
=
utf8.char
(
128520
)
end
redis
:
set
(
'games:noughts_and_crosses:'
..
session_id
,
json
.
encode
(
g
))
local
status
=
language
[
'game'
][
'12'
]
local
keyboard
=
game
.
get_keyboard
(
session_id
,
true
,
language
)
return
mattata
.
send_inline_article
(
inline_query
.
id
,
language
[
'game'
][
'13'
],
language
[
'game'
][
'14'
],
status
,
nil
,
keyboard
)
end
function
game
.
on_message
(
_
,
message
,
_
,
language
)
local
keyboard
=
mattata
.
inline_keyboard
():
row
(
mattata
.
row
():
switch_inline_query_current_chat_button
(
language
[
'game'
][
'16'
],
'/game'
))
local
stats
=
game
.
get_stats
(
message
.
from
.
id
,
language
)
local
output
=
string.format
(
language
[
'game'
][
'15'
],
message
.
from
.
name
)
..
stats
return
mattata
.
send_message
(
message
.
chat
.
id
,
output
,
nil
,
true
,
false
,
nil
,
keyboard
)
end
return
game
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 15, 11:01 PM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
77335
Default Alt Text
game.lua (13 KB)
Attached To
Mode
R69 mattata
Attached
Detach File
Event Timeline