chillavanilla / teeworldseconmod Goto Github PK
View Code? Open in Web Editor NEWA python script which communicates with teeworlds server log as input and econ connection as output.
License: MIT License
A python script which communicates with teeworlds server log as input and econ connection as output.
License: MIT License
Funny flag times like:
13.37
4.20
6.66
6.9
Should be announced in chat and showed in '/archivements'
also maybe detect double kills by checking time diff between kills
4 [5d1e214b][game]: pickup player='3:Niklas 32' item=1/0
3 [5d1e214c][game]: pickup player='3:Niklas 32' item=1/0
2 [5d1e214c][chat]: 2:-2:nameless tee: ❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤<de1f>
1 [5d1e214c][server]: cid=0 cmd='say "[WARNING] UnicodeDecodeError! Please contact an admin."'
897067 [5d1e214c][chat]: *** [WARNING] UnicodeDecodeError! Please contact an admin.
No python error but the server stopped.
[2019-10-03 16:56:49][game]: pickup player='1:machine' item=1
[2019-10-03 16:56:49][game]: team_join player='0:ChillerDragon' team=0->-1
[2019-10-03 16:56:49][server]: cid=0 cmd='say "[ERROR] invalid team=0->-1"'
[2019-10-03 16:56:49][chat]: *** [ERROR] invalid team=0->-1
IDs are now hex or not anymore? idk support both.
New timestamp.
New info about shooting: teeworlds/teeworlds#2206
if someone uses the name '/help' or '/top5' the command gets executed every time they use chat.
So they can't use the '/rank' command.
CTF runs kinda fine for now but DM and TDM are pretty untested.
Detect gametype at round start and count kills as score in non CTF gametypes to choose a winner on game end.
Check sv_scorelimit
on round start to early track wins and looses not only for 1000.
to fix the bug:
sv_scorelimit
1000 is strongly recommended if scorelimit is lower the wins and looses will be calculated on new round start. So all players who leave during end screen won't be tracked. If the scorelimit is 1000 the wins and looses will be saved instantly on the 10th capture.
Add a new thread that prints every x seconds a random announcement from a file to the chat.
Use this to advertise admin contact.
Anti spam system. If spamming many commands in short time is detected that player can't use any commands for x seconds.
File "./src/main.py", line 115, in <module>
main(sys.argv[1:])
File "./src/main.py", line 112, in main
MainLoop()
File "./src/main.py", line 77, in MainLoop
HandleData(line[1:20], line[21:]) # cut off the timestamp
File "./src/main.py", line 66, in HandleData
game.HandleGame(timestamp, data)
File "/home/chiller/git/TeeworldsEconMod/src/game.py", line 97, in HandleGame
flag.HandleFlapCap07(data)
File "/home/chiller/git/TeeworldsEconMod/src/flag.py", line 75, in HandleFlapCap07
__HandleFlagCap(p, m.group("time"), flag_color)
File "/home/chiller/git/TeeworldsEconMod/src/flag.py", line 21, in __HandleFlagCap
achievements.CheckFlag(player_obj, time)
File "/home/chiller/git/TeeworldsEconMod/src/achievements.py", line 48, in CheckFlag
if player.UpdateAchievement(player, "satan"):
AttributeError: 'Player' object has no attribute 'UpdateAchievement'
Either as normal tem setting or even as start script argument. Add config to force the port which then gets passed to the teeworlds server as econ port. Also allow the value random.
The use case for this is security through non default/changing ports. And no port jamming during fast restarts (saves nerves and time during development).
sh_force_port=8303
sh_force_port=random
The kills deaths and spree info is too much for a join message.
Maybe only show kill rank or create a new gloabl rank depending on points calculated by all the ranks mixed somehow.
Make sure nothing breaks if a player uses the name ' victim='
or other similar names currently used for parsing.
[2020-03-03 21:40:18][game]: kill killer='9:0:EviL' victim='2:1:nameless' weapon=4 special=1
[2020-03-03 21:40:18][game]: pickup player='1:toBsucht' item=3
[2020-03-03 21:40:19][chat]: 4:1:♾: а следующее оружие у тебя на чем? ))
[2020-03-03 21:40:19][game]: flag_return player='7:kroxa' team=0
[2020-03-03 21:40:20][game]: pickup player='3:BITCH' item=1
[2020-03-03 21:40:20][game]: pickup player='2:nameless' item=1
[2020-03-03 21:40:20][game]: pickup player='7:kroxa' item=1
[2020-03-03 21:40:20][game]: pickup player='7:kroxa' item=1
[2020-03-03 21:40:20][game]: pickup player='7:kroxa' item=1
[2020-03-03 21:40:21][game]: pickup player='2:nameless' item=2
[2020-03-03 21:40:23][chat]: 5:1:CHERO: пробел)
[2020-03-03 21:40:23][game]: pickup player='8:tota' item=1
[2020-03-03 21:40:23][game]: pickup player='3:BITCH' item=1
[2020-03-03 21:40:23][game]: pickup player='8:tota' item=1
[2020-03-03 21:40:23][game]: pickup player='3:BITCH' item=1
[2020-03-03 21:40:23][game]: pickup player='8:tota' item=1
[2020-03-03 21:40:23][game]: pickup player='1:toBsucht' item=0
[2020-03-03 21:40:24][game]: pickup player='8:tota' item=0
[2020-03-03 21:40:25][game]: pickup player='5:CHERO' item=1
[2020-03-03 21:40:25][game]: pickup player='5:CHERO' item=1
[2020-03-03 21:40:25][game]: pickup player='5:CHERO' item=1
[2020-03-03 21:40:26][game]: flag_capture player='1:toBsucht' team=0 time=31.74
[2020-03-03 21:40:26][game]: pickup player='8:tota' item=3
[2020-03-03 21:40:26][game]: pickup player='9:EviL' item=0
[2020-03-03 21:40:26][game]: pickup player='9:EviL' item=0
[2020-03-03 21:40:26][game]: pickup player='9:EviL' item=0
[2020-03-03 21:40:26][game]: flag_grab player='3:BITCH' team=1
[2020-03-03 21:40:27][game]: pickup player='2:nameless' item=2
[2020-03-03 21:40:27][game]: pickup player='1:toBsucht' item=2
[2020-03-03 21:40:27][game]: flag_grab player='9:EviL' team=0
[2020-03-03 21:40:27][server]: cid=0 cmd='say "[ERROR] name missmatch p.name='None' name='EviL'"'
[2020-03-03 21:40:27][chat]: *** [ERROR] name missmatch p.name='None' name='EviL'
If one tee is alone on the server and maybe trying to beat his flag time it doesnt make too much sense to count selfkills.
I'm getting this constructed line, I think trailing slashes should kinda be sanitized with python
config:
sh_tw_path=/home/jxsl13.tw/teeworlds/build/
py_file_database=stats/vanilla_ctf_stats.db
Kinda disturbed by that double slash there.
...
[TEM] No stats/ folder found in your teeworlds directory
[TEM] should be at: /home/jxsl13.tw/teeworlds/build//stats
...
Maybe remove trailing slash from every configuration line that expects a directory and add it manually yourself when constructing the final path.
Use new name recognizion techniques and only print stats of one player.
Maybe splitt in global and round stats and remove '/stats_all' from command list.
Make sure that only valuable flags with enemys online get counted
and provide a /rank and /top command for it
The player.flag_time variable stores values like "red" and "blue".
After 2 years running in production the first user report came in that complained about fakers destroying the Kill Death Ratio. I always was somehow bothered by it and thus deaths are intentionally hidden in the stats commands.
It would be nice for users that REALLY want this to be able to provide something. I thought about two options:
Complete lock of specific names. Could be unlocked by moderators manually. And are autokicked otherwise.
Lock names to ip range. If the user has a fixed ip range from his provider or even a static ip this might be an option.
[5da1c1eb][server]: 'foo' -> 'foo'
[5da1c1eb][server]: player has entered the game. ClientID=a addr=185.XXX.XXX.XXX:2073
[5da1c1eb][chat]: *** 'foo' entered and joined the blue team
[5da1c1eb][game]: team_join player='10:foo' team=1
[5da1c1eb][chat]: *** [ERROR] teamchange failed id=10 data=[game]: team_join player='10:foo' team=1
The player is stored with id 'a' and looked up by id 10.
Currently player objects fetched by iterating over the players array all over the place.
It would probably be smarter to use a Dictionary with the name being the key.
My setup is currently using this extension: https://github.com/Microsoft/vscode-python
And then code .
in the root of the repo.
Add to your .vscode/settings.json
the following line:
{
"python.autoComplete.extraPaths": ["./src"]
}
Make sure a killing spree is never overwritten by a worse highscore compared to a outdated record. Can happen on 0.7 when both tees have the same name or if two servers are running.
It can happen that both players break the killing spree highscore while both are online. If then the player with the better highscore leaves first the other one overwrites it with a worse highscore.
just after few commands I got banned. It's bad!
top5 are full of nameless tee
(1)nameless tee
and (1)
add atleast an config option to filter them out of the rankings
If the script gets started with nohup or by any other non interactive script it should behave differently. It should exit with an error code on invalid log path and not prompt the user to create one.
Add a config to automatically veto all votes containing given values. Example:
Also cover the new vote reason setting in tests and make sure it does not break 0.6
it would be pretty cool to give the option to atleast hide the command message from one team
expect is missing as a dependency in the readme
[2019-11-23 20:01:24][chat]: 2: ФФФФФФФ(invalid utf8)
[2019-11-23 20:01:24][chat]: -1: : *** [WARNING] UnicodeDecodeError! Please contact an admin.
Invalid names are possible that trigger this warning when they use chat. So this can get very annoying. It is probably best idea to move all warnings to the admin console only.
Do not trigger discord ping when a admin is authed (bot.py). And block echo commands like !reload_settings for moderators (tem).
Add a option to concatenate multiple tem.settings files with a include <path>
syntax.
Do not wait for disconnect or round end so players can see rank improving while fast capping and nobody can overwrite with worse new highscore.
Use icon console echo command to reparse/update settings file. For live server tweaks.
[2020-07-13 12:14:40][server]: player is ready. ClientID=2 addr=XXX.XXX.XXX.XXX:44228
[2020-07-13 12:14:40][game]: Teams are balanced (red=2 blue=1)
[2020-07-13 12:14:40][game]: kill killer='6:1:i3slkiller' victim='6:1:i3slkiller' weapon=-3 special=0
[2020-07-13 12:14:40][game]: team_join player='6:i3slkiller' team=1->0
[2020-07-13 12:14:40][game]: kill killer='1:0:Dillon' victim='1:0:Dillon' weapon=-3 special=0
[2020-07-13 12:14:40][game]: team_join player='1:Dillon' team=0->1
[2020-07-13 12:14:40][game]: team_join player='2:(connecting)' team=0->1
[2020-07-13 12:14:40][server]: player has entered the game. ClientID=2 addr=XXX.XXX.XXX.XXX:44228
[2020-07-13 12:14:40][game]: team_join player='2:zyles' team=1
[2020-07-13 12:14:40][game]: Teams are balanced (red=1 blue=2)
[2020-07-13 12:14:40][server]: cid=0 cmd='say "[stats] '(connecting)' kills: 237 deaths: 238 killingspree: 10"'
[2020-07-13 12:14:40][chat]: *** [stats] '(connecting)' kills: 237 deaths: 238 killingspree: 10
[2020-07-13 12:14:40][server]: cid=0 cmd='say "[ERROR] untracked namechange from '(connecting)' to 'zyles'"'
[2020-07-13 12:14:40][chat]: *** [ERROR] untracked namechange from '(connecting)' to 'zyles'
line: 0:-2:el pro: ¡VB 89YUOL
Traceback (most recent call last):
File "./bot.py", line 46, in <module>
main()
File "./bot.py", line 38, in main
HandleData(line)
File "./bot.py", line 24, in HandleData
requests.post("https://discordapp.com/api/webhooks/" + token, data={"content": line})
File "/home/chiller/.local/lib/python3.5/site-packages/requests/api.py", line 116, in post
return request('post', url, data=data, json=json, **kwargs)
File "/home/chiller/.local/lib/python3.5/site-packages/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/home/chiller/.local/lib/python3.5/site-packages/requests/sessions.py", line 519, in request
prep = self.prepare_request(req)
File "/home/chiller/.local/lib/python3.5/site-packages/requests/sessions.py", line 462, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/home/chiller/.local/lib/python3.5/site-packages/requests/models.py", line 316, in prepare
self.prepare_body(data, files, json)
File "/home/chiller/.local/lib/python3.5/site-packages/requests/models.py", line 507, in prepare_body
body = self._encode_params(data)
File "/home/chiller/.local/lib/python3.5/site-packages/requests/models.py", line 104, in _encode_params
v.encode('utf-8') if isinstance(v, str) else v))
UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc2' in position 13: surrogates not allowed
^@^@[21:29:59][game]: leave player='3:name'
^@^@Traceback (most recent call last):
File "./src/main.py", line 126, in <module>
main(sys.argv[1:])
File "./src/main.py", line 123, in main
MainLoop()
File "./src/main.py", line 88, in MainLoop
HandleData(line[1:20], line[21:]) # cut off the timestamp
File "./src/main.py", line 61, in HandleData
player.HandlePlayerLeave(data[:-1]) # chop of newline
File "/home/chiller/git/TeeworldsEconMod/src/player.py", line 159, in HandlePlayerLeave
SaveAndDeletePlayer(player)
File "/home/chiller/git/TeeworldsEconMod/src/player.py", line 72, in SaveAndDeletePlayer
SaveStats(player)
File "/home/chiller/git/TeeworldsEconMod/src/save_stats.py", line 9, in SaveStats
return SaveStatsSQL(player)
File "/home/chiller/git/TeeworldsEconMod/src/sql_stats.py", line 192, in SaveStatsSQL
player.a_haxx0r, player.a_blazeit, player.a_satan, player.a_virgin
sqlite3.OperationalError: database is locked
Do not wait for disconnect or round end so players can see rank improving while fast capping and nobody can overwrite with worse new highscore.
Anti farm for flag caps and grabs same as killingsprees and maybe move these values somewhere in a config file.
After teeworlds/teeworlds#2243 is fixed. Make sure the script can handle it well. Also with killing sprees and so on.
^@^@[18:37:55][server]: player is ready. ClientID=15 addr=84.XXX.XXX.XXX:58675
^@^@echo "[WARNING] UnicodeDecodeError! Please contact an admin."
[18:37:55][server]: cid=0 cmd='echo "[WARNING] UnicodeDecodeError! Please contact an admin."'
^@^@[18:37:55][Console]: [WARNING] UnicodeDecodeError! Please contact an admin.
^@^@[18:37:55][server]: player has entered the game. ClientID=15 addr=84.82.88.251:58675
^@^@say "[ERROR] teamchange failed id=15 data=[game]: team_join player='15:flappie' team=1"
say " id=12 name='e6aJloBcblPe'"
say " id=6 name='Who'"
say " id=3 name='ChillerDragon'"
say " id=10 name='Spulae Mulae'"
say " id=8 name='Whis'"
say " id=2 name='Cap'tain roc'"
say " id=0 name='Ponny'"
say " id=5 name='naamloos tie'"
say " id=7 name='nameless tee'"
say " id=11 name='Soleil'"
say " id=13 name='Swap'"
say " id=1 name='teeless name'"
say " id=4 name='Stechus Kaktus'"
say " id=9 name='martinus magnus'"
[18:37:55][server]: cid=0 cmd='say "[ERROR] teamchange failed id=15 data=[game]: team_join player='15:flappie' team=1"'
^@^@[18:37:55][chat]: *** [ERROR] teamchange failed id=15 data=[game]: team_join player='15:flappie' team=1
Keep track of all the caps and count red and blue caps to check on new round who has more flags.
Also create a temporary player variable which holds the current team to reward in win or loose on round end.
Maybe count disconnecting while being in the worse team as loose or what ever. Or do something else agianst disconnect before loose. And also keep in mind that many players leave on deathscreen and the new round message in the server log arrives at the end of the deathscreen. So maybe detect scorelimit somehow or always trigegr game end on 10 flags and warn that lower scorelimits than 1000 might influence winnning stats.
The crashlog:
[chat]: *** 'leooelisabeth' has left the game
[game]: leave player='9:leooelisabeth'
[chat]: *** The red flag was captured by 'Mr. Teeseeks' (13.06 seconds)
[teamchat]: 3:1:nameless tee: ннннннннннннеееееееееееееккккккккккккккккккккууууууууууууууууууууццццццццццццццццццццйцййцввваааааааааапппппппппппппппÑ
Traceback (most recent call last):
File "/home/chiller/git/TeeworldsEconMod/src/main.py", line 48, in MainLoop
line = sys.stdin.readline()
File "/usr/lib/python3.4/codecs.py", line 313, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd1 in position 276: invalid continuation byte
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/chiller/git/TeeworldsEconMod/src/main.py", line 97, in <module>
main(sys.argv[1:])
File "/home/chiller/git/TeeworldsEconMod/src/main.py", line 94, in main
MainLoop()
File "/home/chiller/git/TeeworldsEconMod/src/main.py", line 55, in MainLoop
say("[WARNING] UnicodeDecodeError! Please contact an admin.")
NameError: name 'say' is not defined
[12:26:47][chat]: 2:1:monad: someone joinning red?
[12:27:00][chat]: 1:1:Boycraft: nope
[12:27:21][chat]: 1:1:Boycraft: hooray
[12:27:48][server]: player is ready. ClientID=0 addr=127.XXX.XXX.XXX:15682
[12:27:49][server]: player has entered the game. ClientID=0 addr=127.XXX.XXX.XXX:15682
say "[stats] 'DIVYAM' kills: 261 deaths: 571 killingspree: 5"
[12:27:49][server]: cid=0 cmd='say "[stats] 'DIVYAM' kills: 261 deaths: 571 killingspree: 5"'
[12:27:49][chat]: *** [stats] 'DIVYAM' kills: 261 deaths: 571 killingspree: 5
[12:28:05][server]: player is ready. ClientID=6 addr=5.XXX.XXX.XXX:21605
say "[ERROR] teamchange failed id=6 data=[game]: team_join player='6:(connecting)' team=0->1"
say " id=3 name='MAHmut'"
say " id=1 name='Boycraft'"
say " id=5 name='E=mc^2'"
say " id=2 name='monad'"
say " id=4 name='Puldcross'"
say " id=0 name='DIVYAM'"
Seems like it is possible that a invalid (connecting)
player can change the team. Probably caused by balance.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.