This repository has been archived by the owner on Mar 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathlobby.lua
304 lines (274 loc) · 8.92 KB
/
lobby.lua
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
-- made exclusively for discord: 232641555398131712
local command = {}
local function parser( self, args )
local fn = self[args[1]]
if fn then
return fn( { table.unpack( args, 2, #args ) } )
end
return false
end
local function tokenizer( text )
if #text == 0 then
return
end
local args = {}
for token in text:gmatch( "%g+" ) do
if #args == 0 then
token = token:lower()
end
args[#args + 1] = token
end
return parser( command, args )
end
local function var( name, val, mt )
local t = type( val )
if t == 'table' then
if not mt then
mt = {
__call = parser
}
end
setmetatable( val, mt )
elseif t ~= 'function' then
return
end
command[name:lower()] = val
end
local function is_lobby_leader( steamid )
if not steamid then
steamid = steam.GetSteamID()
end
return party.GetLeader() == steamid
end
local predict_match_group = {}
do
local matchgroups = party.GetAllMatchGroups()
for k in pairs( matchgroups ) do
local i = 1
for j = 2, #k do
local s = k:sub( i, j )
predict_match_group[s:lower()] = k
predict_match_group[s] = k
end
end
end
local queue_func = function( str )
if not gamecoordinator.ConnectedToGC() then
print( "failed to queue : not connected to GC" )
end
local matchgroups = party.GetAllMatchGroups()
for k, mode in pairs( matchgroups ) do
if predict_match_group[str] == k then
local id = mode:GetID()
local reasons = party.CanQueueForMatchGroup( mode )
local shouldQueue = gamerules.GetCurrentMatchGroup() ~= id or gamerules.GetCurrentMatchGroup() == id and
gamecoordinator.InEndOfMatch()
if shouldQueue then
if reasons == true then
party.QueueUp( mode )
else
for k, v in pairs( reasons ) do
-- print( v )
end
end
end
end
end
end
local q__proxy = {}
local q___mt = setmetatable( {
count = 0
}, {
__index = q__proxy,
__newindex = function( self, index, value )
local c, k = self.count, q__proxy[index]
index = predict_match_group[index]
if not index then
return
end
if not value and k then
q__proxy[index] = nil
c = c - 1
elseif value and not k then
q__proxy[index] = {}
c = c + 1
goto assign
elseif value and k then
c = c
goto assign
end
goto continue
::assign::
value = math.min( math.max( math.abs( value ), 0.75 ), 7200 )
q__proxy[index]['delay'] = value
q__proxy[index]['time'] = os.clock() + value
::continue::
self.count = c
callbacks.Unregister( 'Draw', 'auto_queue' )
if c > 0 then
callbacks.Register( 'Draw', 'auto_queue', function()
for mode, t in pairs( q__proxy ) do
if os.clock() > t['time'] then
t['time'] = os.clock() + t['delay']
queue_func( mode )
end
end
end )
end
end
} )
-- TODO : rework queue -> support queue standby + clear nextgame queue + clear standby queue
-- TODO : add an option to stop queue if we're already ingame in that gamemode.
var( 'queue', function( args )
local str, time = table.unpack( args )
if str == 'clear' then
for k, g in pairs( party.GetAllMatchGroups() ) do
party.CancelQueue( g )
end
q__proxy = {}
q___mt.count = 0
return callbacks.Unregister( 'Draw', 'auto_queue' )
end
q___mt[predict_match_group[str]] = tonumber( time )
queue_func( str )
end )
-- tf_party_debug
-- tf_party_incoming_invites_debug
local session_ban = {}
local ban_duration = 600 -- 10 minutes
local function leader_lobby_method( args, callback, fmt )
if not is_lobby_leader() then
return print( 'I\'m not lobby leader.' )
end
local any = table.concat( args, ' ' )
local guessName = any:match( "^[\"']+(.-)[\"']+$" ) -- pattern devil
local indexOrSteam64 = tonumber( any )
local stack = party.GetMembers()
for index, steam3 in ipairs( stack ) do
local name = steam.GetPlayerName( steam3 )
local steam64 = steam.ToSteamID64( steam3 )
-- LuaFormatter off
if indexOrSteam64 == index
or indexOrSteam64 == steam64
or guessName == name
or any == steam3 then
-- LuaFormatter on
local template = {
['party_member_index'] = index,
['steam3'] = steam3,
['steam64'] = steam64,
['name'] = name
}
if fmt then
print( (fmt:gsub( '(%b{})', function( w )
return template[w:sub( 2, -2 )] or w
end )) )
end
return callback( steam3 ), steam3
end
end
end
local function generic_func( cmd, steamid, fmt )
local ref = 'share my lobby'
local original = gui.GetValue( ref )
local steam64 = steam.ToSteamID64( steamid )
gui.SetValue( ref, 1 )
client.Command( 'tf_party_force_update', true )
client.Command( cmd .. steam64, true )
local template = {
['steam64'] = steam64,
['name'] = steam.GetPlayerName( steam64 )
}
if fmt then
print( (fmt:gsub( '(%b{})', function( w )
return template[w:sub( 2, -2 )] or w
end )) )
end
gui.SetValue( ref, original )
end
var( 'invite', function( args )
generic_func( 'tf_party_invite_user ', args[1], '[SUISEX] Inviting user to lobby: {name}, steamid64: {steam64}' )
end )
var( 'join', function( args )
generic_func( 'tf_party_request_join_user ', args[1], '[SUISEX] Join user\'slobby: {name}, steamid64: {steam64}' )
end )
var( 'kick', function( args )
leader_lobby_method( args, party.KickMember,
'[SUISEX] Kicking : {name}, index: {party_member_index}, steamid3: {steam3}' )
end )
var( 'transfer', function( args )
leader_lobby_method( args, party.PromoteMemberToLeader,
'[SUISEX] Giving lobby ownership to : {name}, index: {party_member_index}, steamid3: {steam3}' )
end )
var( 'ban', function( args )
local _, steam3 = leader_lobby_method( args, party.KickMember,
'[SUISEX] Temp Banning : {name}, index: {party_member_index}, steamid3: {steam3}' )
if steam3 then
session_ban[steam3] = os.clock() + ban_duration
end
end )
local function PartySay( message )
client.Command( string.format( 'tf_party_chat %q', message:gsub( '"', "'" ) ), true )
end
var( 'fun', function()
PartySay( 'There\'s no fun' )
end )
-- todo : table format would look nice :) + 3 conditional check is dumb.
var( 'info', {
['lobby'] = function( args )
local index = tonumber( args[1] )
local members = party.GetMembers()
if index and #members < index then
index = nil
end
for i = index and index or 1, index and index or #members do
local name, a = steam.GetPlayerName( members[i] ), party.GetMemberActivity( i )
print( string.format( 'index: %d, name: %s, online: %s, lobbyID: %d, clientver: %d', i, name, a:IsOnline(),
a:GetLobbyID(), a:GetClientVersion() ) )
end
end
} )
-- TODO: ... this looks rough.
local e = {
['lobby_updated'] = function( event )
for index, steam3 in ipairs( party.GetPendingMembers() ) do
if session_ban[steam3] < os.clock() then
party.KickMember( steam3 )
print( '[SUISEX] Expected ' .. steam3 .. ' cannot join for:' .. os.clock() - session_ban[steam3] )
end
end
end
}
callbacks.Register( 'FireGameEvent', function( event )
local v = e[event:GetName()]
if v then
v( event )
end
end )
callbacks.Register( 'SendStringCmd', function( cmd )
if tokenizer( cmd:Get() ) ~= false then
cmd:Set( '' )
end
end )
if party.GetGroupID() == nil then
print "Creating a party shared object"
party.QueueUp( party.GetAllMatchGroups()['SpecialEvent'] )
end
callbacks.Register( 'Draw', function()
draw.SetFont( 21 )
draw.Color( 255, 255, 255, 255 )
draw.Text( 200, 280, 'NumMatchInvites: ' .. gamecoordinator.GetNumMatchInvites() )
end )
-- local x, y = 900, 200
-- local dcp, sort_dcp = gamecoordinator.GetDataCenterPingData(), {}
-- for datacenter, ping in pairs( dcp ) do
-- sort_dcp[#sort_dcp + 1] = { datacenter, ping }
-- end
-- table.sort( sort_dcp, function( l, r )
-- return l[2] < r[2]
-- end )
-- for index, t in ipairs( sort_dcp ) do
-- print( index )
-- draw.Text( x, y, t[1] .. ': ' .. t[2] )
-- y = y + 20
-- end