-
Notifications
You must be signed in to change notification settings - Fork 2
/
mvd.lua
414 lines (319 loc) · 13.5 KB
/
mvd.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
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
--[[
LUA MVD script for the extended hifi-q2admin (https://github.com/hifi/q2admin/)
------------------------------
Copyright (C) 2012 Paul Klumpp
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
------------------------------
Function:
Automatically starts recording of Q2Pro Multi View Demos within the Action Quake2 - TNG Mod when match starts.
It also deletes the mvd-file if match countdown failed.
Fully working initial version by Paul Klumpp, 2012-11-12
Please record your big changes here and increase version number:
1.6: ability to give cvars as parameters to the exec_script
1.5: exchanged all "say" with bprintf or dprintf
1.4: added round_state check, added whether a cvar "q2a_mvd_autorecord" needs to be set so the recording happens runs (for lrcon usage)
1.3: added "exec_script_on_system_after_recording" for config.lua. BE CAREFUL with those shellscripts!
1.2: Checks for (Action Quake 2 and sv_mvd_enable != 0). And added useful mvd defaults for scoreboard
1.1: Even works on aq2-tng public teamplay mode now
1.0: All working on aq2-tng matchmode
0.9: Last Debug
config.lua example, with all options:
------------------------------
plugins = {
some_other_plugin = {
blah = "blah"
},
mvd = {
mvd_webby = 'http://mvd2.quadaver.org',
exec_script_on_system_after_recording = '/home/gameservers/quake2/plugins/mvd_transfer.sh',
exec_script_cvars_as_parameters = {"q2a_mvd_file", "game", "hostname"},
needs_cvar_q2a_mvd_autorecord = false
}
}
------------------------------
!! Notice the "," in front of "mvd = {"
--]]
local game = gi.cvar("game", "").string
local sv_mvd_enable = gi.cvar("sv_mvd_enable", "").string
if game ~= "action" or sv_mvd_enable == "0" or sv_mvd_enable == "" or sv_mvd_enable == nil then
gi.dprintf("mvd.lua WARNING: This script only loads when game is 'action' and when sv_mvd_enable is '1' or '2'!\n")
return 0
end
-- if we came to here, it's action!
local version = "1.6hau"
gi.AddCommandString("sets q2a_mvd "..version.."\n")
local mvd_webby -- configure this one in the config.lua
local exec_script_on_system_after_recording -- configure this one in the config.lua
local exec_script_cvars_as_parameters -- configure this one in the config.lua
local needs_cvar_q2a_mvd_autorecord -- configure this one in the config.lua
-- state vars
local teams_ready = {}
local mvd_records = false
local started_on_round_state = ""
local mvd_pathfile = ""
local mvd_file = ""
gi.cvar_set("q2a_mvd_file", mvd_file)
---- small helper functions follow: ----
function file_exists(fname)
local f=io.open(fname,"r")
if f~=nil then
io.close(f)
return true
else
return false
end
end
function string_strip(badstring)
goodstring = badstring
goodstring = string.gsub(goodstring, "%W", "")
return goodstring
end
function reset_ready_state()
for k in pairs (teams_ready) do
teams_ready[k] = nil
end
end
function get_round_state()
local teamplay = gi.cvar("teamplay", "").string
if teamplay == "1" then
local cvar_t1 = gi.cvar("t1", "").string
local cvar_t2 = gi.cvar("t2", "").string
local cvar_t3 = gi.cvar("t3", "").string
local rstate = ""..cvar_t1.." "..cvar_t2.." "..cvar_t3..""
return rstate
end
return 0
end
---- big helper functions follow: ----
function mvd_os_exec(script)
gi.dprintf('mvd.lua mvd_os_exec(): '..script..'\n')
local returnstuff = os.execute(script)
gi.dprintf('mvd.lua mvd_os_exec(): returns: '..returnstuff..'\n')
return returnstuff
end
function mvd_start_recording()
-- if teamplay == 1 then save round state .. for later usage -
-- this is to know if record stopping also can delete the newly recorded mvd, because the rounds did not happen.
started_on_round_state = get_round_state()
-- build filename
local now = os.date("%Y-%m-%d_%H%M%S")
local mapname = gi.cvar("mapname", "").string
local filename = now
for k,v in pairs(teams_ready) do
filename = filename .. "_" .. v
--gi.AddCommandString("say starting team: "..v.."\n")
end
filename = filename.."_"..mapname
gi.AddCommandString("mvdrecord -z "..filename.."\n")
mvd_file = filename..".mvd2.gz"
gi.cvar_set("q2a_mvd_file", mvd_file)
mvd_pathfile = game.."/demos/"..mvd_file
mvd_records = true
local hostname = gi.cvar("hostname", "").string
gi.bprintf(PRINT_CHAT, "MVD: '%s' MVD2 recording started: %s\n", hostname, mvd_file)
end
function mvd_stop_and_delete()
local current_round_state = get_round_state()
if mvd_records == true then
if current_round_state == started_on_round_state then
gi.AddCommandString("mvdstop\n")
mvd_records = false
-- if file exists in game dir, delete it
--$game demos/lala.mvd2.gz
if file_exists(mvd_pathfile) then
if os.remove(mvd_pathfile) then
gi.bprintf(PRINT_HIGH, 'Deleted the MVD2: %s\n', mvd_file)
else
gi.dprintf('mvd.lua mvd_stop_and_delete(): Problems deleting MVD2: %s\n', mvd_file)
end
end
mvd_pathfile = ""
mvd_file = ""
gi.cvar_set("q2a_mvd_file", mvd_file)
else
gi.bprintf(PRINT_CHAT, 'MVD: Be quick to ready up again! MVD2 is still recording!\n')
end
end
end
function mvd_script_exec()
if exec_script_on_system_after_recording ~= nil then
if exec_script_cvars_as_parameters ~= nil then
gi.dprintf('mvd.lua mvd_script_exec(): getting cvars for custom script execution.\n')
local exec_str = ""
for k,v in ipairs(exec_script_cvars_as_parameters) do
kstr = gi.cvar(v, "").string
gi.dprintf('mvd.lua mvd_script_exec(): cvar %s, %s: %s\n', k, v, kstr)
exec_str = exec_str..' "'..kstr..'"'
end
mvd_os_exec(exec_script_on_system_after_recording..exec_str)
else
gi.dprintf('mvd.lua mvd_script_exec(): standard script execution.\n')
-- using standard execution: <mvd_file> and <game>
mvd_os_exec(exec_script_on_system_after_recording..' "'..mvd_file..'" "'..game..'"')
end
end
end
function mvd_stop()
if mvd_records == true then
gi.dprintf('mvd.lua mvd_stop(): stopping MVD recording...\n')
gi.AddCommandString("mvdstop\n")
mvd_records = false
-- if file exists in game dir, advertise it:
if file_exists(mvd_pathfile) then
--$game demos/lala.mvd2.gz
if mvd_webby ~= nil then
gi.bprintf(PRINT_CHAT, 'MVD: Download the MVD2(%s) - %s\n', mvd_file, mvd_webby)
else
gi.bprintf(PRINT_CHAT, 'MVD: Download the MVD2: %s\n', mvd_file)
end
mvd_script_exec()
end
mvd_pathfile = ""
mvd_file = ""
gi.cvar_set("q2a_mvd_file", mvd_file)
end
end
---- q2admin hook functions follow: ----
function q2a_load(config)
gi.dprintf("mvd.lua q2a_load(): "..version.." for Action Quake 2 loaded.\n")
mvd_webby = config.mvd_webby
exec_script_on_system_after_recording = config.exec_script_on_system_after_recording
exec_script_cvars_as_parameters = config.exec_script_cvars_as_parameters
needs_cvar_q2a_mvd_autorecord = config.needs_cvar_q2a_mvd_autorecord
if mvd_webby == nil then
gi.dprintf("mvd.lua q2a_load(): You may define 'mvd_webby' in the config.lua file.\n")
-- safe default:
mvd_webby = nil
end
if exec_script_on_system_after_recording == nil then
gi.dprintf("mvd.lua q2a_load(): You may define 'exec_script_on_system_after_recording' in the config.lua file.\n")
-- safe default:
exec_script_on_system_after_recording = nil
end
if exec_script_cvars_as_parameters == nil then
gi.dprintf("mvd.lua q2a_load(): You may define 'exec_script_cvars_as_parameters' in the config.lua file.\n")
-- safe default:
exec_script_cvars_as_parameters = nil
end
if needs_cvar_q2a_mvd_autorecord == nil then
gi.dprintf("mvd.lua q2a_load(): You may define 'needs_cvar_q2a_mvd_autorecord' in the config.lua file.\n")
-- safe default:
needs_cvar_q2a_mvd_autorecord = false
end
-- set some working defaults (workarounds) if game is action...
if game == "action" then
gi.AddCommandString('set sv_mvd_nomsg 0\n')
gi.AddCommandString('set sv_mvd_begincmd "putaway; h_cycle;"\n')
gi.AddCommandString('set sv_mvd_scorecmd "h_cycle;"\n')
gi.AddCommandString('alias h_cycle "h_cycle_sb; h_cycle_sb; h_cycle_sb; h_cycle_sb; h_cycle_sb;"\n')
gi.AddCommandString('alias h_cycle_sb "wait; help; wait 75; help; wait 100; putaway;"\n')
gi.AddCommandString('set mvd_default_map wfall\n')
end
end
function LevelChanged(level)
gi.dprintf("mvd.lua LevelChanged(): it has been changed to %s\n", level)
-- reset teams ready state
reset_ready_state()
-- if mvd is recording, stop mvd recording and advertise
mvd_stop()
end
function LogMessage(msg)
--debug of all incoming msg:
--gi.AddCommandString("say "..msg.."\n")
local team_ready = string.match(msg, "(.+) is ready to play!")
if team_ready ~= nil then
-- strip whitespace and bad chars
team_ready = string_strip(team_ready)
--gi.AddCommandString("say adding team: "..team_ready.."\n")
table.insert(teams_ready,team_ready)
return true
end
local team_notready = string.match(msg, "(.+) is no longer ready to play!")
if team_notready ~= nil then
-- strip whitespace and bad chars
team_notready = string_strip(team_notready)
for k,v in pairs(teams_ready) do
if v == team_notready then
table.remove(teams_ready, k)
end
end
return true
end
local match = string.match(msg, "The round will begin in 20 seconds!")
if match ~= nil then
-- if mvd not recording then start mvd record
if mvd_records == false then
if needs_cvar_q2a_mvd_autorecord == true then
local q2a_mvd_autorecord = gi.cvar("q2a_mvd_autorecord", "0").string
if q2a_mvd_autorecord ~= "" and q2a_mvd_autorecord ~= "0" then
mvd_start_recording()
end
else
mvd_start_recording()
end
end
return true
end
local match = string.match(msg, "Both Teams Must Be Ready!")
if match ~= nil then
-- if mvd is currently recording and t1, t2 == 0, then stop mvd recording and delete file
mvd_stop_and_delete()
return true
end
-- this message can't be catched by LogMessage .. .:(
--local match = string.match(msg, "Recording local MVD to (.+)")
--if match ~= nil then
-- mvd_pathfile = match
-- mvd_records = true
-- gi.AddCommandString("say MVD2 recording started: "..mvd_pathfile.."\n")
-- return true
--end
local match = string.match(msg, "Scores and time .+ reset.+by request of captains")
if match ~= nil then
-- reset teams ready state
reset_ready_state()
-- if mvd is currently recording and t1, t2 == 0, then stop mvd recording and delete file
mvd_stop_and_delete()
return true
end
local match = string.match(msg, "Match is over, waiting for next map, please vote a new one..")
if match ~= nil then
-- reset teams ready state
reset_ready_state()
-- if mvd is recording, stop mvd recording and advertise
mvd_stop()
return true
end
local match = string.match(msg, "Game ending at:.+")
if match ~= nil then
-- reset teams ready state
reset_ready_state()
-- if mvd is recording, stop mvd recording and advertise
mvd_stop()
return true
end
end -- of LogMessage
-- The round will begin in 20 seconds!
-- if mvd is not recording then start mvd record
-- Both Teams Must Be Ready!
-- if mvd is currently recording and t1, t2 == 0, then stop mvd recording and delete file
-- Recording local MVD to demos/1352750130_Team#2_Team#1.mvd2.gz
-- save full filename
-- set mvd_records state to true
-- Scores and time was resetted by request of captains
-- if mvd is currently recording, then stop mvd recording and delete file
-- Match is over, waiting for next map, please vote a new one..
-- if mvd is currently recording, then stop mvd recording (and keep file) and advertise!
--[[
# vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 autoindent:
# kate: space-indent on; indent-width 4; mixedindent off;
--]]