te4.py 5.42 KB
Newer Older
Trevor Cappallo's avatar
Trevor Cappallo committed
1 2 3 4 5 6 7 8 9
import os
import discord
import re
import pprint
import requests
import platform
from discord.ext import tasks, commands
from discord.ext.commands import Bot

10 11 12
reGame = re.compile('\s*([0-9.]+)\s+([0-9a-fA-F]+)\s+"(.*?)"'
'\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+"(.*?)"\s+"(.*?)"'
'\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s*',re.MULTILINE)
Trevor Cappallo's avatar
Trevor Cappallo committed
13

14 15
reSummary = re.compile('^\s*(.*)\*\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+'
'([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+MG\-on.*$',re.MULTILINE)
Trevor Cappallo's avatar
Trevor Cappallo committed
16

17
games=[]
Trevor Cappallo's avatar
Trevor Cappallo committed
18
recentlySaid=[]
19
lastData = ""
20 21
currentGames={}
cnt=0
Trevor Cappallo's avatar
Trevor Cappallo committed
22 23

def parse_server_poll(data):
24 25 26 27 28
    global lastData

    if data != lastData:
        print(data)
        lastData = data
Trevor Cappallo's avatar
Trevor Cappallo committed
29 30 31 32
    m = reSummary.match(data)
    (listing, summary) = (m.groups()[0], m.groups()[1:])

    m = reGame.findall(listing)
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
    r = {'games': [
            {
            'ip': a[0],
            'port': int(a[1], 16),
            'name': a[2],
            'game_info': [
                {
                    'tiredness': (x>>27) & ((1<<1)-1),
                    'preview': (x>>24) & ((1<<3)-1),
                    'control_mode': (x>>22) & ((1<<2)-1),
                    'unused': (x>>21) & ((1<<1)-1),
                    'game_per_set': (x>>18) & ((1<<3)-1),
                    'court': (x>>9) & ((1<<9)-1),
                    'skill_mode': (x>>7) & ((1<<2)-1),
                    'nb_set': (x>>5) & ((1<<2)-1),
                    'player_cfg': (x>>2) & ((1<<3)-1),
                    'trial': (x>>0) & ((1<<2)-1),
                } for x in [int(a[3], 16)]][0],
            'max_ping': int(a[4], 16),
            'elo': int(a[5], 16),
            'nb_game': int(a[6], 16),
            'tagline': a[7],
            'score': a[8],
            'other_elo': int(a[9], 16),
            'give_up_rate': int(a[10], 16),
            'reputation': int(a[11], 16),
            'creation_time': int(a[12], 16),
            } for a in m],
Trevor Cappallo's avatar
Trevor Cappallo committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
        'summary': summary}
    
    return(r)
    
TOKEN = open("token.txt", "r").readline()

intents = discord.Intents.default()
intents.members = False
intents.typing = False
intents.presences = False
intents.messages = True

ch = None
bot = Bot(command_prefix='!', intents=intents)

@bot.event
async def on_ready():
    global ch
    print(f"Logged in as {bot.user.name}")
    print(f"Discord.py API version: {discord.__version__}")
    print(f"Python version: {platform.python_version()}")
    print(f"Running on: {platform.system()} {platform.release()} ({os.name})")
    print("-------------------")
84
    channels = [c for g in bot.guilds for c in g.text_channels]
Trevor Cappallo's avatar
Trevor Cappallo committed
85 86 87 88 89
    ch = discord.utils.get(channels, name="find-a-game")
    status_task.start()

@tasks.loop(seconds=15.0)
async def status_task():
Trevor Cappallo's avatar
cleanup  
Trevor Cappallo committed
90
    global games, cnt, currentGames, recentlySaid
Trevor Cappallo's avatar
Trevor Cappallo committed
91 92
    data = requests.get("https://www.managames.com/tennis/online/TE4_ServerList.php?Poll=1")
    info = parse_server_poll(data.text.replace('\n',' '))
93
    games = info['games']
94 95
    out=[]
    nix=[]
96 97 98
    previewStrings = ('None', 'Service', 'Service + Rally', 'All + Danger Zone', 'All + Danger Zone + Aiming')
    skillStrings = ('Free', 'Fair', 'Realistic')
    controlStrings = ('Simulation', 'Arcade', 'Elite')
99

100
    for ongoing in currentGames.keys():
101
        if ongoing not in [x['name'] for x in games]:
102 103 104 105 106
            out += [f"The {ongoing} game is finished. Final score: {currentGames[ongoing]['score']}"]
            nix += [ongoing]
    for xin in nix:
        del currentGames[xin]

107 108 109 110 111
    if len(games)>0 or len(out)>0:
        for game in games:
            s = ""
            if game['ip']=='0' and ' vs ' in game['name']:
                if game['name'] not in currentGames.keys():
Trevor Cappallo's avatar
Trevor Cappallo committed
112 113
                    players = game['name'].split(' vs ')
                    s = f"{players[0]} started a game with {players[1]}."
114
                currentGames[game['name']] = game
Trevor Cappallo's avatar
Trevor Cappallo committed
115
            else:
116
                try:
Trevor Cappallo's avatar
cleanup  
Trevor Cappallo committed
117
                    s = f"{game['name']} (elo: {game['elo']}, rep: {game['reputation']}%) wants to play a {game['game_info']['nb_set']}-set match. (Preview: {previewStrings[game['game_info']['preview']]}. Control: {controlStrings[game['game_info']['control_mode']]}. Skill: {skillStrings[game['game_info']['skill_mode']]}.)"
118 119 120
                except:
                    pprint.pprint(game)
                    s = ""
121 122
                if len(game['tagline'])>0:
                    s += f" Comment: {game['tagline']}"
123
            if s != "" and s not in recentlySaid:
Trevor Cappallo's avatar
Trevor Cappallo committed
124 125 126 127
                out += [s]
                recentlySaid.append(s)
        if len(recentlySaid) > 5:
            recentlySaid = recentlySaid[-5:]
Trevor Cappallo's avatar
Trevor Cappallo committed
128
        
Trevor Cappallo's avatar
cleanup  
Trevor Cappallo committed
129 130 131
        for line in out:
            pprint.pprint(line)
            await ch.send(line)
132 133
    
    if len(games) == 0:
Trevor Cappallo's avatar
Trevor Cappallo committed
134
        recentlySaid = []
135
    cnt+=1
Trevor Cappallo's avatar
Trevor Cappallo committed
136 137 138 139

bot.run(TOKEN)


140
# 123.45.67.89 10E1 "Kate Kirby" B180B21 96 3B9 9 "test msg" "..." 0 16 32 61780D39 * 0 0 0 37 1E9C4 0 MG-on
Trevor Cappallo's avatar
Trevor Cappallo committed
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
# * 0 0 0 37 1E9C4 0 MG-on

# For each server, you'll see this :
# Ip Port "Name" GameInfo MaxPing Elo NbGame "TagLine" "Score" OtherElo GiveUpRate Reputation CreationTimeInMs

# Ip is 0 if the game is already started.

# All numbers are hexadecimal.

# GameInfo is a bitfield like this :
# - Trial : 2 bits
# - PlayerCfg : 3 ; 0 => singles ; 2 => Vs doubles ; 3 => Coop doubles (IIRC)
# - NbSet : 2
# - SkillMode : 2
# - Court : 9 (will eventually be changed to 2 string, 1 for stadium & 1 for the surface)
# - GamePerSet : 3
# - <unused> : 1
# - ControlMode : 2
# - Preview : 3
160
# - Tiredness : 1