Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mega Man Battle Network 3: Implement New Game #1198

Merged
merged 179 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from 172 commits
Commits
Show all changes
179 commits
Select commit Hold shift + click to select a range
1d79f5d
Initializes MMBN3 world with empty files
digiholic Aug 20, 2022
416c0e9
Adds item names to item dict
digiholic Aug 21, 2022
770f75f
Adds locations and names
digiholic Aug 21, 2022
fe3d3aa
Adds skeleton of MMBN3Client. Mostly copy pasta from OOT
digiholic Aug 21, 2022
b6f3119
Fixed some style and formatting
digiholic Aug 21, 2022
600ac7b
More incremental Lua tests
digiholic Aug 24, 2022
1080029
Adds all locations and checking to Lua connector
digiholic Aug 28, 2022
e4f8a2d
Made class definitions for TextPet Parser
digiholic Aug 29, 2022
97dbb79
Begun connecting item delivery system through lua and textpet
digiholic Sep 6, 2022
b29119c
Lua Connection can now send test items
digiholic Sep 9, 2022
e448d49
Item Delivery is now parameterized. Test command can send any chip
digiholic Sep 12, 2022
7670741
Adds the ability to send non-chip items
digiholic Sep 14, 2022
f8482a3
Fixes name errors in python client
digiholic Sep 14, 2022
583330b
Fixes count for zenny, attempts to fix bugfrags
digiholic Sep 14, 2022
33be227
Fixes an issue where you always received 255 bugfrags
digiholic Sep 14, 2022
fe47a74
Converts zenny and bugfrag amounts to little endian bytecode
digiholic Sep 15, 2022
f807b27
Checks game state before sending chips
digiholic Sep 15, 2022
5cb6f55
Adds in some animation reset instructions during item get message
digiholic Sep 16, 2022
21471f1
Stores previously collected item index in save, re-sends missing items
digiholic Sep 18, 2022
a99ca6a
Adds title screen check before sending locations
digiholic Sep 18, 2022
1312a0f
Adds progressive undernet check
digiholic Sep 19, 2022
880c349
Added library for lzss decoding bits of rom
digiholic Sep 21, 2022
58ee332
More progress on parsing text events from ROM
digiholic Sep 22, 2022
2a77503
Adds a way to inject messages into ScriptArchive data structure and g…
digiholic Sep 23, 2022
56050ff
Adds Item definitions, passes to client
digiholic Sep 24, 2022
a669083
Adds regions and item collection rules
digiholic Sep 26, 2022
deb460b
Touched up a few names and values that have changed in preparation fo…
digiholic Sep 28, 2022
6f58d12
Modifying messages via item is now successful
digiholic Oct 1, 2022
a68b638
Added generate_output hook to generate ROM data
digiholic Oct 2, 2022
1da6b7a
Generates ROM successfully
digiholic Oct 5, 2022
95b3d6f
Fixes navi cust give index
digiholic Oct 5, 2022
fc04151
Whoops forgot to wrap this in brackets
digiholic Oct 6, 2022
9a06034
Injects extra scripts for undernet rankings
digiholic Oct 6, 2022
8658d7e
Programs had ammount and color swapped
digiholic Oct 6, 2022
63779cd
Prompts the user for their username when connecting
digiholic Oct 7, 2022
85866bb
Adds flagClear to the list of commands to avoid overwriting
digiholic Oct 8, 2022
392e0af
Fixes message box crashes and several other multiworld issues
digiholic Oct 11, 2022
3e78f56
Fixes IDs and names of several items and locations
digiholic Oct 14, 2022
b459670
Added .gba to gitignore
digiholic Oct 14, 2022
92657a6
Fixes compatibility after recent rebase
digiholic Oct 14, 2022
978a837
Fixes some locations and items that are otherwise unobtainable
digiholic Oct 16, 2022
a75e157
Attempts to make a working launcher in the installer
digiholic Oct 16, 2022
90c2954
Creates installer and fixes several inaccessible locations
digiholic Oct 19, 2022
a9841eb
Many minor changes to items, locations, and requirements made during …
digiholic Nov 4, 2022
d20dcd0
Adds an info page for MMBN3
digiholic Nov 4, 2022
0461849
Fixes failing tests by removing duplicate IDs and properly marking pr…
digiholic Nov 4, 2022
7bc03e4
Accidentally forgot to un-remove the thing
digiholic Nov 4, 2022
a2cc85a
Whoops, changed this by accident
digiholic Nov 4, 2022
fbf63f9
Merge remote-tracking branch 'upstream/main' into mmbn3-world
digiholic Nov 5, 2022
cf70211
Updates self.world references to self.multiworld
digiholic Nov 5, 2022
51df456
Merge branch 'main' into mmbn3-world
digiholic Nov 5, 2022
100d87a
Merge branch 'main' into mmbn3-world
digiholic Nov 7, 2022
f798772
Fixes imports to use from imports instead of using the namespace
digiholic Nov 7, 2022
5ce91b2
Merge branch 'main' into mmbn3-world
digiholic Nov 7, 2022
eb1105c
Removed some leftover merge artifacts from inno setup
digiholic Nov 8, 2022
af23b4e
Puts back that darned signtool line again
digiholic Nov 8, 2022
3cf9b97
Merge branch 'main' into mmbn3-world
digiholic Nov 9, 2022
e6912a8
Merge branch 'main' into mmbn3-world
digiholic Nov 9, 2022
88e494f
Adds Overworld Metro keys as items
digiholic Nov 12, 2022
d1714f4
Adds TamaCode and puts shortcuts behind cyber passes
digiholic Nov 12, 2022
376b21b
Fixes Numberman code 16 check
digiholic Nov 12, 2022
58a4c44
Fixes metro access logic and adds text to metro
digiholic Nov 12, 2022
48e9afe
Merge pull request #53 from digiholic/33-change-overworld-metro-areas…
digiholic Nov 12, 2022
5caa121
Merge branch 'main' into mmbn3-world
digiholic Nov 12, 2022
979e88d
Reworks Lua to fix crashing when many items are queued
digiholic Nov 19, 2022
508c953
Items for other BN3 games for different players are no longer given i…
digiholic Nov 19, 2022
7772f90
Merge branch 'main' into mmbn3-world
digiholic Nov 20, 2022
45a7b14
Merge branch 'main' into mmbn3-world
digiholic Nov 20, 2022
f1840bd
Fixes incorrect Item ID for ACDC Metro
digiholic Nov 20, 2022
22addc8
Merge branch 'main' into mmbn3-world
digiholic Nov 20, 2022
fe198e0
Fixes multi-box text messages
digiholic Nov 27, 2022
55260ac
Adds timer before sending an item
digiholic Nov 27, 2022
3516388
Forgot to remove the second box of SubMems
digiholic Nov 28, 2022
141b0cf
Merge branch 'main' into mmbn3-world
digiholic Nov 29, 2022
6e15853
Updates patch and lua to prevent softlocks and crashes
digiholic Dec 2, 2022
2583aa6
Adds options for extra undernet ranks, exclude jobs
digiholic Dec 2, 2022
dab36fc
Extra GigFreez now gives 20 bugfrags
digiholic Dec 3, 2022
56cd5e4
Additional Progressive Undernets can no longer appear on the WWW Base
digiholic Dec 3, 2022
bdc982d
Merge branch 'main' into mmbn3-world
digiholic Dec 3, 2022
d71be67
Merge branch 'main' into mmbn3-world
digiholic Dec 19, 2022
f585b2c
Moves item signal byte to empty area of flags instead of end of RAM
digiholic Dec 19, 2022
5d4b6f2
Merge branch 'mmbn3-world' of https://github.com/digiholic/Archipelag…
digiholic Dec 19, 2022
3e08b91
Adds Chocolate Shop locations and navi chips to fill them
digiholic Dec 30, 2022
c8ffc4f
Merge branch 'main' into mmbn3-world
digiholic Dec 30, 2022
4998e41
Fixes save crash, and added chocolates to lua
digiholic Jan 1, 2023
874a4d1
Fixes chocolate stand selling out text, removes DrillMan cube in Unde…
digiholic Jan 9, 2023
193c721
Merge branch 'main' into mmbn3-world
digiholic Jan 9, 2023
93af66c
Replaces old messaging system with direct memory manipulation for rec…
digiholic Jan 29, 2023
068ef85
Merge branch 'main' into mmbn3-world
digiholic Jan 29, 2023
e7e3e2d
Removes NDSPY requirements from MMBN3 by manually adapting the GBA's …
digiholic Jan 30, 2023
ec0436e
Merge branch 'main' into mmbn3-world
digiholic Jan 30, 2023
74883ee
Fixes the names of Hospital-1 Locations
digiholic Feb 28, 2023
6ef5468
Merge pull request #58 from digiholic/57-hospital-1-items-are-incorre…
digiholic Feb 28, 2023
49a9906
Adds Canary Bit to avoid sending checks when title screen check fails
digiholic Feb 28, 2023
1613b3b
Merge pull request #59 from digiholic/55-fix-item-checks-on-title-scr…
digiholic Feb 28, 2023
b6debd9
Gaining a cybermetro pass will now open the shortcut immediately
digiholic Feb 28, 2023
57feb51
Merge pull request #60 from digiholic/52-automatically-open-shortcuts…
digiholic Feb 28, 2023
c1ace73
Randomizes the two accessible areas of Undernet 7, adds Hammer as item
digiholic Feb 28, 2023
0176165
Adds new locations to connector lua
digiholic Mar 1, 2023
e01bd9f
Merge pull request #62 from digiholic/56-randomize-undernet-7
digiholic Mar 1, 2023
7321b7a
Injects the name of the item into trade quests
digiholic Mar 3, 2023
4c25788
Merge branch 'main' into mmbn3-world
digiholic Mar 3, 2023
abced54
Fixes copy-paste error in docs
digiholic Mar 3, 2023
d5a22c3
Merge branch 'mmbn3-world' of https://github.com/digiholic/Archipelag…
digiholic Mar 3, 2023
7b16ddc
Fixes merge artifacts and depracated code
digiholic Mar 3, 2023
9e02398
Nut-wafer stand now faces Lan the right way after buying
digiholic Mar 3, 2023
8ee83f7
Removes unused Goal Option and updates the readme to include most rec…
digiholic Mar 3, 2023
34463db
Merge branch 'main' into mmbn3-world
digiholic Mar 3, 2023
5c7ce2c
Touch-ups and formatting changes
digiholic Mar 5, 2023
e796b96
The Great Fillerization update. Dozens of items changed to Filler
digiholic Mar 5, 2023
d9a276a
Replaces instances of Mega Man with MegaMan
digiholic Mar 5, 2023
7a35ecc
Update worlds/mmbn3/docs/en_MegaMan Battle Network 3.md
digiholic Mar 5, 2023
7f2ce13
Update worlds/mmbn3/__init__.py
digiholic Mar 5, 2023
20cf36d
Apply suggestions from code review
digiholic Mar 5, 2023
fbd7467
Changes code ordering to suit base class's
digiholic Mar 5, 2023
77226a4
Merge branch 'mmbn3-world' of https://github.com/digiholic/Archipelag…
digiholic Mar 5, 2023
dbf97dc
assert_generate now checks for roms. Minor text fixes
digiholic Mar 5, 2023
9dd7a45
Makes player specific frequency and excluded location options
digiholic Mar 5, 2023
6f18685
Merge branch 'main' into mmbn3-world
digiholic Mar 6, 2023
2746ef1
Merge branch 'main' into mmbn3-world
digiholic Mar 6, 2023
b245212
Apply suggestions from code review
digiholic Mar 6, 2023
55a8c0a
Addresses suggested changes from PR review
digiholic Mar 6, 2023
3ef6254
Replaces ndspy lz10 with MIT-compliant nlzss lz10
digiholic Mar 7, 2023
599d8fc
Merge branch 'mmbn3-world' of https://github.com/digiholic/Archipelag…
digiholic Mar 7, 2023
a29b783
Merge branch 'main' into mmbn3-world
digiholic Mar 7, 2023
ea15eb3
apworld compatibility fix for mmbn3_options from utils
digiholic Mar 8, 2023
aa16092
Merge branch 'main' into mmbn3-world
digiholic Mar 8, 2023
650d2df
Merge branch 'main' into mmbn3-world
digiholic Mar 8, 2023
4893b7a
Merge branch 'main' into mmbn3-world
digiholic Mar 9, 2023
024ab7b
Addressing more comments by el-u
digiholic Mar 16, 2023
72f3868
APworld will now pull patch from zip folder
digiholic Mar 26, 2023
7407730
Merge branch 'main' into mmbn3-world
digiholic Mar 26, 2023
de1e1e0
Merge branch 'mmbn3-world' of https://github.com/digiholic/Archipelag…
digiholic Mar 26, 2023
2d67fc4
Apply suggestions from code review
digiholic Mar 26, 2023
1c69ec7
Merge branch 'main' into mmbn3-world
digiholic Apr 3, 2023
17aa156
Cleaned up comments for progressive undernet ROM function, moved inde…
digiholic Apr 3, 2023
a352935
Removes improper player-indexed location/item dicts, replaces with wo…
digiholic Apr 3, 2023
cf909a7
Avoids redefining list in progressive undernet ROM function
digiholic Apr 3, 2023
6513ce4
Filler items can no longer be generated beyond their specified amounts
digiholic Apr 3, 2023
41c2604
Fixes list copying issue with item frequencies
digiholic Apr 3, 2023
d4e19eb
Adds BN3 Client Generation back into Launcher settings
digiholic Apr 3, 2023
0c52e3b
Merge branch 'mmbn3-world' of https://github.com/digiholic/Archipelag…
digiholic Apr 4, 2023
f78a2d1
Fixes typos causing huge problems
digiholic Apr 4, 2023
c292973
Fixed non-relative import for apworld
digiholic Apr 4, 2023
e2392a3
Merge branch 'main' into mmbn3-world
digiholic Apr 4, 2023
19571d6
Removes custom enum implementation that broke pickle
digiholic Apr 4, 2023
3a79eee
Merge branch 'main' into mmbn3-world
digiholic Apr 15, 2023
d1603cc
Merge branch 'main' into mmbn3-world
digiholic Apr 24, 2023
09e3f60
Displays message when attempting to load an incorrect ROM, will not a…
digiholic May 8, 2023
7307ead
Merge branch 'main' into mmbn3-world
digiholic May 8, 2023
4d945ff
Filler items can now only be placed once
digiholic May 8, 2023
d57f828
Changes path in setup doc to match Lua path changes
digiholic May 8, 2023
54db8c5
Fixes file extension for MMBN3 file
digiholic May 8, 2023
ed40abb
Replaces magic number with reference to value in NetUtils
digiholic May 8, 2023
516f529
Moves victory rules to set_rules. Removes commented out code
digiholic May 8, 2023
c5cd366
Rewrites Lua script to send block of memory
digiholic May 10, 2023
6c65a19
Merge branch 'main' into mmbn3-world
digiholic May 10, 2023
f3fe51d
Fixes off-by-one error in sending bytes for locations
digiholic May 11, 2023
6d3b85d
Merge branch 'main' into mmbn3-world
digiholic May 19, 2023
4730245
Fixes issue with invalid characters in text parsing, and WWW monitor …
digiholic May 23, 2023
aa2e3c7
Merge branch 'main' into mmbn3-world
digiholic May 25, 2023
f4a274c
Moves trade text injection to init so it has access to options
digiholic May 25, 2023
06d459b
Attempts to split the text boxes for hinted items
digiholic May 25, 2023
767c289
Trade checks now provide hints if the option is set for them
digiholic May 26, 2023
5c05bc2
Merge pull request #63 from digiholic/hinting-trade-text
digiholic May 26, 2023
7e34f7a
Fixes escape character issue for BizHawk 2.9.1
digiholic May 28, 2023
8ea0467
Merge branch 'main' into mmbn3-world
digiholic May 30, 2023
92431c1
Merge branch 'main' into mmbn3-world
digiholic May 31, 2023
f98b5ef
Re-adds desk check that it turns out actually does exist
digiholic May 31, 2023
99a8d25
Updates requirements to mention bizhawk 2.7 instead of 2.3.1
digiholic Jun 1, 2023
cbe41bb
Fixes off-by-one error in command byte counts
digiholic Jun 1, 2023
eea9072
Fixes program color indices
digiholic Jun 14, 2023
16e60d3
Fixes newline PEP violations
digiholic Jun 28, 2023
0a6361b
Reverts an accidental whitespace change made to launcher.py
digiholic Jun 28, 2023
c0d86f0
Fixes URL formatting on link to settings from setup guide
digiholic Jun 28, 2023
ec50da4
Splits several lines in the readme to avoid excessive length
digiholic Jun 28, 2023
786f866
Fixes formatting and (hopefully) reduces cringe of joke in setup doc
digiholic Jun 28, 2023
2f5f7f2
Removes unnecessary constructor
digiholic Jun 28, 2023
aacb0fc
Changes item frequency generation to avoid reusing the same references
digiholic Jun 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ def open_folder(folder_path):
else:
webbrowser.open(folder_path)


digiholic marked this conversation as resolved.
Show resolved Hide resolved
components.extend([
digiholic marked this conversation as resolved.
Show resolved Hide resolved
# Functions
Component("Open host.yaml", func=open_host_yaml),
Expand Down
372 changes: 372 additions & 0 deletions MMBN3Client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,372 @@
import asyncio
import hashlib
import json
import os
import multiprocessing
import subprocess
import zipfile

from asyncio import StreamReader, StreamWriter

import bsdiff4

from CommonClient import CommonContext, server_loop, gui_enabled, \
ClientCommandProcessor, logger, get_base_parser
import Utils
from NetUtils import ClientStatus
from worlds.mmbn3.Items import items_by_id
from worlds.mmbn3.Rom import get_base_rom_path
from worlds.mmbn3.Locations import all_locations, scoutable_locations

SYSTEM_MESSAGE_ID = 0

CONNECTION_TIMING_OUT_STATUS = "Connection timing out. Please restart your emulator, then restart connector_mmbn3.lua"
CONNECTION_REFUSED_STATUS = \
"Connection refused. Please start your emulator and make sure connector_mmbn3.lua is running"
CONNECTION_RESET_STATUS = "Connection was reset. Please restart your emulator, then restart connector_mmbn3.lua"
CONNECTION_TENTATIVE_STATUS = "Initial Connection Made"
CONNECTION_CONNECTED_STATUS = "Connected"
CONNECTION_INITIAL_STATUS = "Connection has not been initiated"
CONNECTION_INCORRECT_ROM = "Supplied Base Rom does not match US GBA Blue Version. Please provide the correct ROM version"

script_version: int = 2

debugEnabled = False
locations_checked = []
items_sent = []
itemIndex = 1

CHECKSUM_BLUE = "6fe31df0144759b34ad666badaacc442"


class MMBN3CommandProcessor(ClientCommandProcessor):
def __init__(self, ctx):
super().__init__(ctx)

def _cmd_gba(self):
"""Check GBA Connection State"""
if isinstance(self.ctx, MMBN3Context):
logger.info(f"GBA Status: {self.ctx.gba_status}")

def _cmd_debug(self):
"""Toggle the Debug Text overlay in ROM"""
global debugEnabled
debugEnabled = not debugEnabled
logger.info("Debug Overlay Enabled" if debugEnabled else "Debug Overlay Disabled")


class MMBN3Context(CommonContext):
command_processor = MMBN3CommandProcessor
game = "MegaMan Battle Network 3"
items_handling = 0b001 # full local

def __init__(self, server_address, password):
super().__init__(server_address, password)
self.gba_streams: (StreamReader, StreamWriter) = None
self.gba_sync_task = None
self.gba_status = CONNECTION_INITIAL_STATUS
self.awaiting_rom = False
self.location_table = {}
self.version_warning = False
self.auth_name = None
self.slot_data = dict()
self.patching_error = False

async def server_auth(self, password_requested: bool = False):
if password_requested and not self.password:
await super(MMBN3Context, self).server_auth(password_requested)

if self.auth_name is None:
self.awaiting_rom = True
logger.info("No ROM detected, awaiting conection to Bizhawk to authenticate to the multiworld server")
return

logger.info("Attempting to decode from ROM... ")
self.awaiting_rom = False
self.auth = self.auth_name.decode("utf8").replace('\x00', '')
logger.info("Connecting as "+self.auth)
await self.send_connect(name=self.auth)

def run_gui(self):
from kvui import GameManager

class MMBN3Manager(GameManager):
logging_pairs = [
("Client", "Archipelago")
]
base_title = "Archipelago MegaMan Battle Network 3 Client"

self.ui = MMBN3Manager(self)
self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI")

def on_package(self, cmd: str, args: dict):
if cmd == 'Connected':
self.slot_data = args.get("slot_data", {})
print(self.slot_data)

class ItemInfo:
id = 0x00
sender = ""
type = ""
count = 1
itemName = "Unknown"
itemID = 0x00 # Item ID, Chip ID, etc.
subItemID = 0x00 # Code for chips, color for programs
itemIndex = 1

def __init__(self, id, sender, type):
self.id = id
self.sender = sender
self.type = type

def get_json(self):
json_data = {
"id": self.id,
"sender": self.sender,
"type": self.type,
"itemName": self.itemName,
"itemID": self.itemID,
"subItemID": self.subItemID,
"count": self.count,
"itemIndex": self.itemIndex
}
return json_data


def get_payload(ctx: MMBN3Context):
global debugEnabled

items_sent = []
for i, item in enumerate(ctx.items_received):
item_data = items_by_id[item.item]
new_item = ItemInfo(i, ctx.player_names[item.player], item_data.type)
new_item.itemIndex = i+1
new_item.itemName = item_data.itemName
new_item.type = item_data.type
new_item.itemID = item_data.itemID
new_item.subItemID = item_data.subItemID
new_item.count = item_data.count
items_sent.append(new_item)

return json.dumps({
"items": [item.get_json() for item in items_sent],
"debug": debugEnabled
})


async def parse_payload(payload: dict, ctx: MMBN3Context, force: bool):
# Game completion handling
if payload["gameComplete"] and not ctx.finished_game:
await ctx.send_msgs([{
"cmd": "StatusUpdate",
"status": ClientStatus.CLIENT_GOAL
}])
ctx.finished_game = True

# Locations handling
if ctx.location_table != payload["locations"]:
ctx.location_table = payload["locations"]
locs = [loc.id for loc in all_locations
if check_location_packet(loc, ctx.location_table)]
await ctx.send_msgs([{
"cmd": "LocationChecks",
"locations": locs
}])

# If trade hinting is enabled, send scout checks
if ctx.slot_data.get("trade_quest_hinting", 0) == 2:
scouted_locs = [loc.id for loc in scoutable_locations
if check_location_scouted(loc, payload["locations"])]
await ctx.send_msgs([{
"cmd": "LocationScouts",
"locations": scouted_locs,
"create_as_hint": 2
}])


def check_location_packet(location, memory):
if len(memory) == 0:
return False
# Our keys have to be strings to come through the JSON lua plugin so we have to turn our memory address into a string as well
location_key = hex(location.flag_byte)[2:]
byte = memory.get(location_key)
if byte is not None:
return byte & location.flag_mask


def check_location_scouted(location, memory):
if len(memory) == 0:
return False
location_key = hex(location.hint_flag)[2:]
byte = memory.get(location_key)
if byte is not None:
return byte & location.hint_flag_mask


async def gba_sync_task(ctx: MMBN3Context):
logger.info("Starting GBA connector. Use /gba for status information.")
if ctx.patching_error:
logger.error('Unable to Patch ROM. No ROM provided or ROM does not match US GBA Blue Version.')
while not ctx.exit_event.is_set():
error_status = None
if ctx.gba_streams:
(reader, writer) = ctx.gba_streams
msg = get_payload(ctx).encode()
writer.write(msg)
writer.write(b'\n')
try:
await asyncio.wait_for(writer.drain(), timeout=1.5)
try:
# Data will return a dict with up to four fields
# 1. str: player name (always)
# 2. int: script version (always)
# 3. dict[str, byte]: value of location's memory byte
# 4. bool: whether the game currently registers as complete
data = await asyncio.wait_for(reader.readline(), timeout=10)
data_decoded = json.loads(data.decode())
reported_version = data_decoded.get("scriptVersion", 0)
if reported_version >= script_version:
if ctx.game is not None and "locations" in data_decoded:
# Not just a keep alive ping, parse
asyncio.create_task((parse_payload(data_decoded, ctx, False)))
if not ctx.auth:
ctx.auth_name = bytes(data_decoded["playerName"])

if ctx.awaiting_rom:
logger.info("Awaiting data from ROM...")
await ctx.server_auth(False)
else:
if not ctx.version_warning:
logger.warning(f"Your Lua script is version {reported_version}, expected {script_version}."
"Please update to the latest version."
"Your connection to the Archipelago server will not be accepted.")
ctx.version_warning = True
except asyncio.TimeoutError:
logger.debug("Read Timed Out, Reconnecting")
error_status = CONNECTION_TIMING_OUT_STATUS
writer.close()
ctx.gba_streams = None
except ConnectionResetError:
logger.debug("Read failed due to Connection Lost, Reconnecting")
error_status = CONNECTION_RESET_STATUS
writer.close()
ctx.gba_streams = None
except TimeoutError:
logger.debug("Connection Timed Out, Reconnecting")
error_status = CONNECTION_TIMING_OUT_STATUS
writer.close()
ctx.gba_streams = None
except ConnectionResetError:
logger.debug("Connection Lost, Reconnecting")
error_status = CONNECTION_RESET_STATUS
writer.close()
ctx.gba_streams = None
if ctx.gba_status == CONNECTION_TENTATIVE_STATUS:
if not error_status:
logger.info("Successfully Connected to GBA")
ctx.gba_status = CONNECTION_CONNECTED_STATUS
else:
ctx.gba_status = f"Was tentatively connected but error occurred: {error_status}"
elif error_status:
ctx.gba_status = error_status
logger.info("Lost connection to GBA and attempting to reconnect. Use /gba for status updates")
else:
try:
logger.debug("Attempting to connect to GBA")
ctx.gba_streams = await asyncio.wait_for(asyncio.open_connection("localhost", 28922), timeout=10)
ctx.gba_status = CONNECTION_TENTATIVE_STATUS
except TimeoutError:
logger.debug("Connection Timed Out, Trying Again")
ctx.gba_status = CONNECTION_TIMING_OUT_STATUS
continue
except ConnectionRefusedError:
logger.debug("Connection Refused, Trying Again")
ctx.gba_status = CONNECTION_REFUSED_STATUS
continue


async def run_game(romfile):
options = Utils.get_options().get("mmbn3_options", None)
if options is None:
auto_start = True
else:
auto_start = options.get("rom_start", True)
if auto_start:
import webbrowser
webbrowser.open(romfile)
elif os.path.isfile(auto_start):
subprocess.Popen([auto_start, romfile],
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)


async def patch_and_run_game(apmmbn3_file):
base_name = os.path.splitext(apmmbn3_file)[0]

with zipfile.ZipFile(apmmbn3_file, 'r') as patch_archive:
try:
with patch_archive.open("delta.bsdiff4", 'r') as stream:
patch_data = stream.read()
except KeyError:
raise FileNotFoundError("Patch file missing from archive.")
rom_file = get_base_rom_path()

with open(rom_file, 'rb') as rom:
rom_bytes = rom.read()

patched_bytes = bsdiff4.patch(rom_bytes, patch_data)
patched_rom_file = base_name+".gba"
with open(patched_rom_file, 'wb') as patched_rom:
patched_rom.write(patched_bytes)

asyncio.create_task(run_game(patched_rom_file))


def confirm_checksum():
rom_file = get_base_rom_path()
if not os.path.exists(rom_file):
return False

with open(rom_file, 'rb') as rom:
rom_bytes = rom.read()

basemd5 = hashlib.md5()
basemd5.update(rom_bytes)
return CHECKSUM_BLUE == basemd5.hexdigest()


if __name__ == "__main__":
Utils.init_logging("MMBN3Client")

async def main():
multiprocessing.freeze_support()
parser = get_base_parser()
parser.add_argument("patch_file", default="", type=str, nargs="?",
help="Path to an APMMBN3 file")
args = parser.parse_args()
checksum_matches = confirm_checksum()
if checksum_matches:
if args.patch_file:
asyncio.create_task(patch_and_run_game(args.patch_file))

ctx = MMBN3Context(args.connect, args.password)
if not checksum_matches:
ctx.patching_error = True
ctx.server_task = asyncio.create_task(server_loop(ctx), name="Server Loop")
if gui_enabled:
ctx.run_gui()
ctx.run_cli()

ctx.gba_sync_task = asyncio.create_task(gba_sync_task(ctx), name="GBA Sync")
await ctx.exit_event.wait()
ctx.server_address = None
await ctx.shutdown()

if ctx.gba_sync_task:
await ctx.gba_sync_task

import colorama

colorama.init()

asyncio.run(main())
colorama.deinit()
4 changes: 4 additions & 0 deletions Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,10 @@ def get_default_options() -> OptionsType:
"wargroove_options": {
"root_directory": "C:/Program Files (x86)/Steam/steamapps/common/Wargroove"
},
"mmbn3_options": {
"rom_file": "Mega Man Battle Network 3 - Blue Version (USA).gba",
"rom_start": True
},
"adventure_options": {
"rom_file": "ADVNTURE.BIN",
"display_msgs": True,
Expand Down
Loading