1
0
mirror of synced 2024-12-01 00:57:18 +01:00
bemaniutils/bemani/utils/trafficgen.py

674 lines
18 KiB
Python

import argparse
import sys
from typing import Any, Dict, Optional
import yaml
from bemani.client import ClientProtocol, BaseClient
from bemani.client.iidx import (
IIDXTricoroClient,
IIDXSpadaClient,
IIDXPendualClient,
IIDXCopulaClient,
IIDXSinobuzClient,
IIDXCannonBallersClient,
IIDXRootageClient,
)
from bemani.client.jubeat import (
JubeatSaucerClient,
JubeatSaucerFulfillClient,
JubeatPropClient,
JubeatQubellClient,
JubeatClanClient,
JubeatFestoClient,
)
from bemani.client.popn import (
PopnMusicTuneStreetClient,
PopnMusicFantasiaClient,
PopnMusicSunnyParkClient,
PopnMusicLapistoriaClient,
PopnMusicEclaleClient,
PopnMusicUsaNekoClient,
PopnMusicPeaceClient,
PopnMusicKaimeiClient,
)
from bemani.client.ddr import (
DDRX2Client,
DDRX3Client,
DDR2013Client,
DDR2014Client,
DDRAceClient,
)
from bemani.client.sdvx import (
SoundVoltexBoothClient,
SoundVoltexInfiniteInfectionClient,
SoundVoltexGravityWarsS1Client,
SoundVoltexGravityWarsS2Client,
SoundVoltexHeavenlyHavenClient,
)
from bemani.client.museca import (
Museca1Client,
Museca1PlusClient,
)
from bemani.client.reflec import (
ReflecBeat,
ReflecBeatLimelight,
ReflecBeatColette,
ReflecBeatGroovinUpper,
ReflecBeatVolzza,
ReflecBeatVolzza2,
)
from bemani.client.bishi import TheStarBishiBashiClient
from bemani.client.mga.mga import MetalGearArcadeClient
def get_client(
proto: ClientProtocol, pcbid: str, game: str, config: Dict[str, Any]
) -> BaseClient:
if game == "pnm-tune-street":
return PopnMusicTuneStreetClient(
proto,
pcbid,
config,
)
if game == "pnm-fantasia":
return PopnMusicFantasiaClient(
proto,
pcbid,
config,
)
if game == "pnm-sunny-park":
return PopnMusicSunnyParkClient(
proto,
pcbid,
config,
)
if game == "pnm-lapistoria":
return PopnMusicLapistoriaClient(
proto,
pcbid,
config,
)
if game == "pnm-eclale":
return PopnMusicEclaleClient(
proto,
pcbid,
config,
)
if game == "pnm-usaneko":
return PopnMusicUsaNekoClient(
proto,
pcbid,
config,
)
if game == "pnm-peace":
return PopnMusicPeaceClient(
proto,
pcbid,
config,
)
if game == "pnm-kaimei":
return PopnMusicKaimeiClient(
proto,
pcbid,
config,
)
if game == "jubeat-saucer":
return JubeatSaucerClient(
proto,
pcbid,
config,
)
if game == "jubeat-saucer-fulfill":
return JubeatSaucerFulfillClient(
proto,
pcbid,
config,
)
if game == "jubeat-prop":
return JubeatPropClient(
proto,
pcbid,
config,
)
if game == "jubeat-qubell":
return JubeatQubellClient(
proto,
pcbid,
config,
)
if game == "jubeat-clan":
return JubeatClanClient(
proto,
pcbid,
config,
)
if game == "jubeat-festo":
return JubeatFestoClient(
proto,
pcbid,
config,
)
if game == "iidx-rootage":
return IIDXRootageClient(
proto,
pcbid,
config,
)
if game == "iidx-cannonballers":
return IIDXCannonBallersClient(
proto,
pcbid,
config,
)
if game == "iidx-sinobuz":
return IIDXSinobuzClient(
proto,
pcbid,
config,
)
if game == "iidx-copula":
return IIDXCopulaClient(
proto,
pcbid,
config,
)
if game == "iidx-pendual":
return IIDXPendualClient(
proto,
pcbid,
config,
)
if game == "iidx-spada":
return IIDXSpadaClient(
proto,
pcbid,
config,
)
if game == "iidx-tricoro":
return IIDXTricoroClient(
proto,
pcbid,
config,
)
if game == "bishi":
return TheStarBishiBashiClient(
proto,
pcbid,
config,
)
if game == "ddr-x2":
return DDRX2Client(
proto,
pcbid,
config,
)
if game == "ddr-x3":
return DDRX3Client(
proto,
pcbid,
config,
)
if game == "ddr-2013":
return DDR2013Client(
proto,
pcbid,
config,
)
if game == "ddr-2014":
return DDR2014Client(
proto,
pcbid,
config,
)
if game == "ddr-ace":
return DDRAceClient(
proto,
pcbid,
config,
)
if game == "sdvx-booth":
return SoundVoltexBoothClient(
proto,
pcbid,
config,
)
if game == "sdvx-infinite-infection":
return SoundVoltexInfiniteInfectionClient(
proto,
pcbid,
config,
)
if game == "sdvx-gravity-wars-s1":
return SoundVoltexGravityWarsS1Client(
proto,
pcbid,
config,
)
if game == "sdvx-gravity-wars-s2":
return SoundVoltexGravityWarsS2Client(
proto,
pcbid,
config,
)
if game == "sdvx-heavenly-haven":
return SoundVoltexHeavenlyHavenClient(
proto,
pcbid,
config,
)
if game == "museca-1":
return Museca1Client(
proto,
pcbid,
config,
)
if game == "museca-1+1/2":
return Museca1PlusClient(
proto,
pcbid,
config,
)
if game == "reflec":
return ReflecBeat(
proto,
pcbid,
config,
)
if game == "reflec-limelight":
return ReflecBeatLimelight(
proto,
pcbid,
config,
)
if game == "reflec-colette":
return ReflecBeatColette(
proto,
pcbid,
config,
)
if game == "reflec-groovin-upper":
return ReflecBeatGroovinUpper(
proto,
pcbid,
config,
)
if game == "reflec-volzza":
return ReflecBeatVolzza(
proto,
pcbid,
config,
)
if game == "reflec-volzza2":
return ReflecBeatVolzza2(
proto,
pcbid,
config,
)
if game == "metal-gear-arcade":
return MetalGearArcadeClient(
proto,
pcbid,
config,
)
raise Exception(f"Unknown game {game}")
def mainloop(
address: str,
port: int,
configfile: str,
action: str,
game: str,
cardid: Optional[str],
verbose: bool,
) -> None:
games = {
"pnm-tune-street": {
"name": "Pop'n Music Tune Street",
"model": "K39:J:B:A:2010122200",
"old_profile_model": "J39:J:A:A",
"avs": None,
},
"pnm-fantasia": {
"name": "Pop'n Music Fantasia",
"model": "L39:J:B:A:2012091900",
"old_profile_model": "K39:J:A:A",
"avs": "2.13.6 r4921",
},
"pnm-sunny-park": {
"name": "Pop'n Music Sunny Park",
"model": "M39:J:B:A:2014061900",
"old_profile_model": "L39:J:A:A",
"avs": "2.15.8 r6631",
},
"pnm-lapistoria": {
"name": "Pop'n Music Lapistoria",
"model": "M39:J:B:A:2015081900",
"old_profile_model": "M39:J:B:A",
"avs": "2.15.8 r6631",
},
"pnm-eclale": {
"name": "Pop'n Music Eclale",
"model": "M39:J:B:A:2016100500",
"old_profile_model": "M39:J:B:A",
"avs": "2.15.8 r6631",
},
"pnm-usaneko": {
"name": "Pop'n Music Usagi to Neko to Shounen no Yume",
"model": "M39:J:B:A:2018101500",
"old_profile_model": "M39:J:B:A",
"avs": "2.15.8 r6631",
},
"pnm-peace": {
"name": "Pop'n Music peace",
"model": "M39:J:B:A:2020092800",
"old_profile_model": "M39:J:B:A",
"avs": "2.15.8 r6631",
},
"pnm-kaimei": {
"name": "Pop'n Music Kaimei riddles",
"model": "M39:J:B:A:2022061300",
"old_profile_model": "M39:J:B:A",
"avs": "2.15.8 r6631",
},
"jubeat-saucer": {
"name": "Jubeat Saucer",
"model": "L44:J:A:A:2014012802",
"avs": "2.15.8 r6631",
},
"jubeat-saucer-fulfill": {
"name": "Jubeat Saucer Fulfill",
"model": "L44:J:B:A:2014111800",
"avs": "2.15.8 r6631",
},
"jubeat-prop": {
"name": "Jubeat Prop",
"model": "L44:J:B:A:2016031700",
"avs": "2.15.8 r6631",
},
"jubeat-qubell": {
"name": "Jubeat Qubell",
"model": "L44:J:D:A:2016111400",
"avs": "2.15.8 r6631",
},
"jubeat-clan": {
"name": "Jubeat Clan",
"model": "L44:J:E:A:2018070901",
"avs": "2.17.3 r8311",
},
"jubeat-festo": {
"name": "Jubeat Festo",
"model": "L44:J:B:A:2022052400",
"avs": "2.17.3 r8311",
},
"iidx-rootage": {
"name": "Beatmania IIDX ROOTAGE",
"model": "LDJ:J:A:A:2019090200",
"avs": "2.17.0 r7883",
},
"iidx-cannonballers": {
"name": "Beatmania IIDX CANNON BALLERS",
"model": "LDJ:J:A:A:2018091900",
"avs": "2.17.0 r7883",
},
"iidx-sinobuz": {
"name": "Beatmania IIDX SINOBUZ",
"model": "LDJ:J:A:A:2017082800",
"avs": "2.16.1 r6901",
},
"iidx-copula": {
"name": "Beatmania IIDX copula",
"model": "LDJ:J:A:A:2016083100",
"avs": "2.16.1 r6901",
},
"iidx-pendual": {
"name": "Beatmania IIDX PENDUAL",
"model": "LDJ:A:A:A:2015080500",
"avs": "2.16.1 r6901",
},
"iidx-spada": {
"name": "Beatmania IIDX SPADA",
"model": "LDJ:A:A:A:2014071600",
"avs": "2.16.1 r6901",
},
"iidx-tricoro": {
"name": "Beatmania IIDX Tricoro",
"model": "LDJ:J:A:A:2013090900",
"avs": "2.15.8 r6631",
},
"bishi": {
"name": "The★BishiBashi",
"model": "IBB:A:A:A:2009092900",
"avs": None,
},
"ddr-x2": {
"name": "DanceDanceRevolution X2",
"model": "JDX:J:A:A:2010111000",
"avs": None,
},
"ddr-x3": {
"name": "DanceDanceRevolution X3 VS 2ndMIX",
"model": "KDX:J:A:A:2012112600",
"avs": "2.13.6 r4921",
},
"ddr-2013": {
"name": "DanceDanceRevolution (2013)",
"model": "MDX:J:A:A:2014032700",
"avs": "2.15.8 r6631",
},
"ddr-2014": {
"name": "DanceDanceRevolution (2014)",
"model": "MDX:A:A:A:2015122100",
"avs": "2.15.8 r6631",
},
"ddr-ace": {
"name": "DanceDanceRevolution A",
"model": "MDX:U:D:A:2017121400",
"avs": "2.15.8 r6631",
},
"sdvx-booth": {
"name": "SOUND VOLTEX BOOTH",
"model": "KFC:J:A:A:2013052900",
"avs": "2.15.8 r6631",
},
"sdvx-infinite-infection": {
"name": "SOUND VOLTEX II -infinite infection-",
"model": "KFC:J:A:A:2014102200",
"avs": "2.15.8 r6631",
},
"sdvx-gravity-wars-s1": {
"name": "SOUND VOLTEX III GRAVITY WARS Season 1",
"model": "KFC:J:A:A:2015111602",
"avs": "2.15.8 r6631",
},
"sdvx-gravity-wars-s2": {
"name": "SOUND VOLTEX III GRAVITY WARS Season 2",
"model": "KFC:J:A:A:2016121900",
"avs": "2.15.8 r6631",
},
"sdvx-heavenly-haven": {
"name": "SOUND VOLTEX IV HEAVENLY HAVEN",
"model": "KFC:J:A:A:2019020600",
"avs": "2.15.8 r6631",
},
"museca-1": {
"name": "MÚSECA",
"model": "PIX:J:A:A:2016071300",
"avs": "2.17.0 r7883",
},
"museca-1+1/2": {
"name": "MÚSECA 1+1/2",
"model": "PIX:J:A:A:2017042600",
"avs": "2.17.0 r7883",
},
"reflec": {
"name": "REFLEC BEAT",
"model": "KBR:A:A:A:2011112300",
"avs": None,
},
"reflec-limelight": {
"name": "REFLEC BEAT limelight",
"model": "LBR:A:A:A:2012082900",
"avs": "2.13.6 r4921",
},
"reflec-colette": {
"name": "REFLEC BEAT colette",
"model": "MBR:J:A:A:2014011600",
"avs": "2.15.8 r6631",
},
"reflec-groovin-upper": {
"name": "REFLEC BEAT groovin'!! Upper",
"model": "MBR:J:A:A:2015102100",
"avs": "2.15.8 r6631",
},
"reflec-volzza": {
"name": "REFLEC BEAT VOLZZA",
"model": "MBR:J:A:A:2016030200",
"avs": "2.15.8 r6631",
},
"reflec-volzza2": {
"name": "REFLEC BEAT VOLZZA 2",
"model": "MBR:J:A:A:2016100400",
"avs": "2.15.8 r6631",
},
"metal-gear-arcade": {
"name": "Metal Gear Arcade",
"model": "I36:J:A:A:2011092900",
"avs": None,
},
}
if action == "list":
for game in sorted([game for game in games]):
print(f'{game} - {games[game]["name"]}')
sys.exit(0)
if action == "game":
if game not in games:
print(f"Unknown game {game}")
sys.exit(2)
config = yaml.safe_load(open(configfile))
print(f'Emulating {games[game]["name"]}')
emu = get_client(
ClientProtocol(
address,
port,
config["core"]["encryption"],
config["core"]["compression"],
verbose,
),
config["core"]["pcbid"],
game,
games[game],
)
emu.verify(cardid)
def main() -> None:
parser = argparse.ArgumentParser(
description="A utility to generate game-like traffic for testing an eAmusement server."
)
parser.add_argument(
"-p", "--port", help="Port to talk to. Defaults to 80", type=int, default=80
)
parser.add_argument(
"-a",
"--address",
help="Address to talk to. Defaults to 127.0.0.1",
type=str,
default="127.0.0.1",
)
parser.add_argument(
"-c",
"--config",
help="Core configuration. Defaults to trafficgen.yaml",
type=str,
default="trafficgen.yaml",
)
parser.add_argument(
"-g",
"--game",
help="The game that should be emulated. Should be one of the games returned by --list",
type=str,
default=None,
)
parser.add_argument(
"-l", "--list", help="List all known games and exit.", action="store_true"
)
parser.add_argument(
"-i",
"--cardid",
help="Use this card ID instead of a random one.",
type=str,
default=None,
)
parser.add_argument(
"-v",
"--verbose",
help="Print packets that are sent/received.",
action="store_true",
default=False,
)
args = parser.parse_args()
if args.list:
action = "list"
game = None
elif args.game:
action = "game"
game = args.game
else:
print("Unknown action to perform. Please specify --game <game> or --list")
sys.exit(1)
game = {
"pnm-19": "pnm-tune-street",
"pnm-20": "pnm-fantasia",
"pnm-21": "pnm-sunny-park",
"pnm-22": "pnm-lapistoria",
"pnm-23": "pnm-eclale",
"pnm-24": "pnm-usaneko",
"pnm-25": "pnm-peace",
"pnm-26": "pnm-kaimei",
"iidx-20": "iidx-tricoro",
"iidx-21": "iidx-spada",
"iidx-22": "iidx-pendual",
"iidx-23": "iidx-copula",
"iidx-24": "iidx-sinobuz",
"iidx-25": "iidx-cannonballers",
"iidx-26": "iidx-rootage",
"jubeat-5": "jubeat-saucer",
"jubeat-5+": "jubeat-saucer-fulfill",
"jubeat-6": "jubeat-prop",
"jubeat-7": "jubeat-qubell",
"jubeat-8": "jubeat-clan",
"jubeat-9": "jubeat-festo",
"ddr-12": "ddr-x2",
"ddr-13": "ddr-x3",
"ddr-14": "ddr-2013",
"ddr-15": "ddr-2014",
"ddr-16": "ddr-ace",
"sdvx-1": "sdvx-booth",
"sdvx-2": "sdvx-infinite-infection",
"sdvx-3s1": "sdvx-gravity-wars-s1",
"sdvx-3s2": "sdvx-gravity-wars-s2",
"sdvx-4": "sdvx-heavenly-haven",
"reflec-1": "reflec",
"reflec-2": "reflec-limelight",
"reflec-3": "reflec-colette",
"reflec-4": "reflec-groovin-upper",
"reflec-5": "reflec-volzza",
"reflec-6": "reflec-volzza2",
"mga": "metal-gear-arcade",
}.get(game, game)
mainloop(
args.address, args.port, args.config, action, game, args.cardid, args.verbose
)
if __name__ == "__main__":
main()