2025-06-05 21:20:53 -04:00
|
|
|
#!/bin/env python3
|
|
|
|
|
|
|
|
|
|
# it is assumed this is run from the root of the project
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import zipfile
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
def generate_ip_script(binary_name: str) -> str:
|
|
|
|
|
return f"""#!/bin/bash
|
|
|
|
|
export RUST_LOG=info
|
|
|
|
|
|
2025-12-07 17:26:09 -05:00
|
|
|
exec ./{binary_name} --ip "0.0.0.0"
|
2025-06-05 21:20:53 -04:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def generate_plain_script(binary_name: str) -> str:
|
|
|
|
|
return f"""#!/bin/bash
|
|
|
|
|
export RUST_LOG=info
|
|
|
|
|
|
2025-12-07 17:26:09 -05:00
|
|
|
exec ./{binary_name}
|
2025-06-05 21:20:53 -04:00
|
|
|
"""
|
|
|
|
|
|
2025-06-06 17:57:37 -04:00
|
|
|
def generate_ip_redirect_script(binary_name: str, port: int) -> str:
|
|
|
|
|
return f"""#!/bin/bash
|
|
|
|
|
export RUST_LOG=info
|
|
|
|
|
|
2025-12-07 17:26:09 -05:00
|
|
|
exec ./{binary_name} --ip "0.0.0.0" --redirect "domain_or_ip_address:{port}"
|
2025-06-06 17:57:37 -04:00
|
|
|
"""
|
|
|
|
|
|
2025-06-05 21:20:53 -04:00
|
|
|
BINARIES_TO_INCLUDE = {
|
2025-10-03 18:08:50 -04:00
|
|
|
#"oj_auth": generate_plain_script,
|
2025-08-03 21:47:25 -04:00
|
|
|
"oj_rc_auth": generate_ip_script,
|
2025-06-05 21:20:53 -04:00
|
|
|
"oj_cdn": generate_ip_script,
|
2025-06-06 17:57:37 -04:00
|
|
|
"oj_rc_chat": lambda name: generate_ip_redirect_script(name, 4537), "oj_rc_chat_room": generate_ip_script,
|
2026-02-14 12:45:55 -05:00
|
|
|
"oj_rc_microtransactions": generate_ip_script,
|
2025-06-06 17:57:37 -04:00
|
|
|
"oj_rc_services": lambda name: generate_ip_redirect_script(name, 4533), "oj_rc_services_room": generate_ip_script,
|
|
|
|
|
"oj_rc_singleplayer": lambda name: generate_ip_redirect_script(name, 4539), "oj_rc_singleplayer_room": generate_ip_script,
|
|
|
|
|
"oj_rc_social": lambda name: generate_ip_redirect_script(name, 4535), "oj_rc_social_room": generate_ip_script,
|
2025-08-03 21:47:25 -04:00
|
|
|
"oj_rc_lobby": lambda name: generate_ip_redirect_script(name, 4541), "oj_rc_lobby_room": lambda name: generate_ip_redirect_script(name, 4542),
|
2025-08-11 20:50:44 -04:00
|
|
|
"oj_rc_multiplayer": generate_ip_script,
|
2026-02-14 11:48:38 -05:00
|
|
|
"oj_rc_factory_web": generate_ip_script,
|
2025-06-05 21:20:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PROJECT_FOLDERS_TO_INCLUDE = [
|
|
|
|
|
"assets",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
# extra assets; not ones in one of the listed folders
|
|
|
|
|
PROJECT_ASSETS_TO_INCLUDE = [
|
2025-10-03 18:08:50 -04:00
|
|
|
"utils/cube_gen.py",
|
|
|
|
|
"LICENSE",
|
|
|
|
|
"README.md",
|
2026-04-09 11:04:39 +00:00
|
|
|
"Dockerfile",
|
|
|
|
|
"docker-compose.release.yml"
|
2025-06-05 21:20:53 -04:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
BLANK_FOLDERS_TO_CREATE = [
|
|
|
|
|
"data/robocraft",
|
|
|
|
|
"data/robocraft/brawldata",
|
|
|
|
|
"data/robocraft/campaigndata",
|
|
|
|
|
"data/robocraft/clanavatar",
|
|
|
|
|
"data/robocraft/customavatars",
|
Implementing upload functionality for ArcAdapter and improving CRF search. (#62)
### Description
This PR implements upload functionality for ArcAdapter and improves CRF search.
adapter.rs
First, regarding the CRF search feature, when there is no search query (i.e., on the default page), there was a bug where sorting by added date and other sort options did not work correctly, so the default query was removed. Also, the added-date sort order was reversed, so that was fixed as well.
Next, about the upload feature.
First, in order to create cube_amounts, which stores in JSON the count of each part of the robot contained at the end of the ROBOT_CUBES table, we count—by type—the number of all byte sequences (part IDs) excluding the first 4 bytes (total part count) and excluding the last 4 bytes (coordinates) out of each following 8 bytes, and then create a JSON string where the keys are the part IDs converted to decimal and the values are the counts.
After that, we insert Base64-encoded data into cube_data and colour_data in ROBOT_CUBES, and insert the above JSON string into cube_amounts.
Next, regarding ROBOT_METADATA, the thumbnail URL is set to the internal CDN, and the actual thumbnail data is saved under data/robocraft/thumbnails.
The added date and expiration date are converted to match the same format as the other data before insertion, and the other data is inserted as-is.
arc.rs
If the requested file is not present in the ZIP file, it was changed to scan the JPG files existing in data/robocraft/thumbnails.
package_release.py
Made it so that data/robocraft/thumbnails is created.
### Game
Robocraft
### Please confirm
- [x] I am the legal owner or represent the owner of all work submitted
- [x] I consent to my submission being added to this FOSS project
- [x] This PR used LLMs to generate some or all of the code changes
Reviewed-on: https://git.ngram.ca/OpenJam/rc-servers/pulls/62
Co-authored-by: MaxSignal <kastera58@gmail.com>
Co-committed-by: MaxSignal <kastera58@gmail.com>
2025-12-13 19:23:07 +00:00
|
|
|
"data/robocraft/factorythumbnails",
|
2025-06-05 21:20:53 -04:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
def add_folder_to_zip(archive: zipfile.ZipFile, root_dir: str):
|
|
|
|
|
archive.mkdir(root_dir)
|
|
|
|
|
for (root, dirs, files) in os.walk(root_dir):
|
|
|
|
|
for f in files:
|
|
|
|
|
archive.write(os.path.join(root, f))
|
|
|
|
|
for d in dirs:
|
|
|
|
|
archive.mkdir(os.path.join(root, d))
|
|
|
|
|
|
|
|
|
|
def main(build_root: str, outfile: str):
|
|
|
|
|
print("Packaging binaries in", build_root)
|
2025-10-03 18:08:50 -04:00
|
|
|
archive = zipfile.ZipFile(outfile, mode="w", compression=zipfile.ZIP_LZMA, compresslevel=9)
|
2025-06-05 21:20:53 -04:00
|
|
|
# handle release binaries
|
|
|
|
|
print("Adding", len(BINARIES_TO_INCLUDE), "binaries")
|
|
|
|
|
for binary_file in BINARIES_TO_INCLUDE.keys():
|
|
|
|
|
fp = os.path.join(build_root, binary_file)
|
|
|
|
|
folder_name = binary_file.replace("oj_", "")
|
|
|
|
|
archive.write(fp, arcname=os.path.join(folder_name, binary_file))
|
|
|
|
|
script_generator = BINARIES_TO_INCLUDE[binary_file]
|
|
|
|
|
if script_generator is not None:
|
|
|
|
|
script = BINARIES_TO_INCLUDE[binary_file](binary_file)
|
|
|
|
|
info = zipfile.ZipInfo(os.path.join(folder_name, "run.sh"))
|
|
|
|
|
info.external_attr = 0o0755 << 16 # unix file permissions
|
|
|
|
|
archive.writestr(info, script)
|
|
|
|
|
# handle release assets
|
|
|
|
|
print("Adding", len(PROJECT_FOLDERS_TO_INCLUDE), "project folders")
|
|
|
|
|
for folder in PROJECT_FOLDERS_TO_INCLUDE:
|
|
|
|
|
add_folder_to_zip(archive, folder)
|
2025-10-03 18:08:50 -04:00
|
|
|
print("Adding", len(PROJECT_ASSETS_TO_INCLUDE), "extra assets")
|
2025-06-05 21:20:53 -04:00
|
|
|
for asset in PROJECT_ASSETS_TO_INCLUDE:
|
2026-04-09 11:04:39 +00:00
|
|
|
if asset == "docker-compose.release.yml":
|
|
|
|
|
archive.write(asset, arcname="docker-compose.yml")
|
|
|
|
|
else:
|
|
|
|
|
archive.write(asset)
|
2025-06-05 21:20:53 -04:00
|
|
|
# handle project setup niceties
|
2025-10-03 18:08:50 -04:00
|
|
|
print("Creating", len(BLANK_FOLDERS_TO_CREATE), "blank folders")
|
2025-06-05 21:20:53 -04:00
|
|
|
for folder in BLANK_FOLDERS_TO_CREATE:
|
|
|
|
|
archive.mkdir(folder)
|
|
|
|
|
archive.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
|
parser.add_argument("build_dir")
|
|
|
|
|
parser.add_argument("--output", default="package.zip")
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
main(args.build_dir, args.output)
|