From 49af026253f98db469dd85b6a75fb5c556b416c6 Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Wed, 21 Dec 2022 12:26:17 +1100 Subject: [PATCH 01/12] Remove obviously obsolete documentation and code --- README.md | 22 ------- RELEASE_JAVA.md | 2 +- RELEASE_PYTHON.md | 12 +--- release_python.py | 142 ---------------------------------------------- 4 files changed, 3 insertions(+), 175 deletions(-) delete mode 100755 release_python.py diff --git a/README.md b/README.md index 671c6b02..0a1c8ba3 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,6 @@ Instead, follow the instructions [here](https://play.battlecode.org/getting-star ## Development -### Website - -While it isn't strictly necessary, running is easier with [Docker](https://docs.docker.com/get-docker/) installed. If you have Windows, I'd also recommend installing [Cygwin](https://www.cygwin.com/), since we have some scripts and programs that won't work with the standard Windows command prompt. (Docker is not strictly necessary, but it makes stuff easier, especially the backend.) - -It's easiest to run the frontend and backend individually, in a separate terminal window for each. For instructions on how to do this, see each of their directories' readmes. - -You could also run both the backend and the frontend in a single Docker container, by running `docker-compose up --build`. But, it's better to run them individuallly. - ### Engine Windows users: Instead of `./gradlew`, use `gradlew` for all commands. @@ -50,20 +42,6 @@ npm run watch which will launch the client on http://localhost:8080 (if available). -### Docs - -You can generate javadocs as follows: - -``` -./gradlew release_docs_zip -Prelease_version=2020.0.0.0.0.1 -``` - -This will create a `zip` file. Unzip and open the `index.html` file in it to view the docs. In particular, looking at the documentation for `RobotController` will be helpful. - -To deploy these docs, get the above zip file, and unzip it. Rename the resulting folder to `javadoc`. Then, put it in `frontend/public`, suchh that there's a `frontend/public/javadoc/index.html`. Then run the frontend deploy process! - -TODO -- these steps ought to simply be in the frontend deploy script. - ## Notes for porting to a new repo When the next edition of Battlecode comes around, it will probably useful to reuse a fair amount of this codebase. Maintaining git history is nice. Use `git-filter-repo` for this: diff --git a/RELEASE_JAVA.md b/RELEASE_JAVA.md index 210a25b1..6bc5ac01 100644 --- a/RELEASE_JAVA.md +++ b/RELEASE_JAVA.md @@ -2,7 +2,7 @@ ## Prereqs -a bash-like shell (windows command prompt won't work for this). Also, zsh (and perhaps other shell environments) don't work to run the frontend deploy script. bash seems to work. +a bash-like shell (windows command prompt won't work for this). npm diff --git a/RELEASE_PYTHON.md b/RELEASE_PYTHON.md index 697f3de3..98b3de44 100644 --- a/RELEASE_PYTHON.md +++ b/RELEASE_PYTHON.md @@ -1,16 +1,8 @@ # HOW TO RELEASE A PYTHON GAME -In general, this guide and script may be out of date. Make any changes as necessary. - -### Preliminaries -- Install the frontend using `npm install`. - - Make sure that if you run `npm run start` in the `frontend` folder, you get a working frontend on `localhost:3000` after a few minutes. -- Install `pandoc` (e.g. using Homebrew) -- Use a bash shell (or something similar — e.g. zsh but not Windows Command Prompt). - -### Release Procedure - Make sure everything is up to date: - `git pull` - Choose a version as $major.$minor.$patch (e.g. 1.32.2) -- Run `./release.py $version`. +- Run `./release.py $version`. This script is now gone, but can be found + [here](https://github.com/battlecode/battlehack20/blob/master/release.py). - Go on Discord and wait for things to catch on fire diff --git a/release_python.py b/release_python.py deleted file mode 100755 index 15ef7b24..00000000 --- a/release_python.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python3 - -""" -In general, this script is out of date. Make any changes as necessary. -(e.g. repo names, year numbers, new frontend deploy process, different specs) -Here's what this script does: -* Generates a comparison link to review the changes -* Adds version number and changelog to specs/specs.md -* Converts `specs.md` into a fancy specs html document (`frontend/public/specs.html`). -* Deploys the frontend. -* Updates setup.py version number. -* Publishes the updated package to PyPi. -* Commits, tags and pushes. - -""" - -import argparse -import subprocess -import os -import datetime - -def main(version): - generate_comparison_link() - - specs(version) - - # TODO should be adapted now that we use markdeep instead - fancy_specs() - - deploy_frontend() - - update_setup_py_version(version) - - publish_pypi() - - commit_tag_push(version) - - -def generate_comparison_link(): - """ - Generate a comparison link like https://github.com/battlecode/battlecode20/compare/commit...commit - comparing the most recent commit with the latest released version. - """ - # get latest tag - latest_tag = subprocess.check_output("git tag --sort=committerdate | tail -1", shell=True).decode("utf-8").strip('\n') - # get commit - commit = subprocess.check_output("git rev-list -n 1 " + latest_tag, shell=True).decode('utf-8').strip('\n') - - # get latest commit - latest = subprocess.check_output("git rev-parse HEAD", shell=True).decode('utf-8').strip('\n') - - # print the link - link = "https://github.com/battlecode/battlehack20/compare/" + commit + "..." + latest - print("Go to the following link and check out the differences:") - print(link) - - # wait until the user says yes - response = input("enter 'y' to proceed with the release: ") - while response != 'y': - response = input("enter 'y' to proceed with the release: ") - - -def specs(version): - with open('specs/specs.md', 'r') as f: - gr = f.read() - - # prompt for changelog in specs, engine - l = ['spec', 'engine'] - d = {i: [] for i in l} - for i in l: - while True: - x = input(i + " change: ") - if x == "": - break - d[i].append(x) - now = datetime.datetime.now() - changelogstring = "- " + version + " (" + str(now.month) + "/" + str(now.day) + "/" + str(now.year)[2:] + ")\n" - for i in l: - changelogstring += " - " + i + " changes:" - if len(d[i]) == 0: - changelogstring += " none\n" - else: - changelogstring += "\n" - for dd in d[i]: - changelogstring += " - " + dd + '\n' - g = gr.split('\n') - for i in range(len(g)): - if "# Changelog" in g[i]: - g.insert(i+2, changelogstring.rstrip()) - if "Current version: " in g[i]: - g[i] = "Current version: " + version - gr = "\n".join(g) - with open('specs/specs.md', 'w') as f: - f.write(gr) - -def fancy_specs(): - os.chdir('specs') - subprocess.call('pandoc specs.md --self-contained --template template.html --toc -o specs.html --metadata pagetitle="Battlehack 2020 Specs"', shell=True) - os.chdir('..') - subprocess.call('cp specs/specs.html frontend/public/specs.html', shell=True) - - -def deploy_frontend(): - os.chdir('frontend') - subprocess.call('./deploy.sh deploy', shell=True) - os.chdir('..') - -def update_setup_py_version(version): - with open('engine/setup.py', 'r') as f: - config = f.read() - config_lines = config.split('\n') - for i in range(len(config_lines)): - if "version=" in config_lines[i]: - p = config_lines[i].split('"') - config_lines[i] = p[0] + '"' + version + '"' + p[2] - config = "\n".join(config_lines) - with open('engine/setup.py', 'w') as f: - f.write(config) - -def publish_pypi(): - os.chdir('engine') - subprocess.call('python3 setup.py sdist bdist_wheel', shell=True) - subprocess.call('twine upload --skip-existing dist/*', shell=True) - os.chdir('..') - -def commit_tag_push(version): - subprocess.call(f'git commit -am "release {version}"', shell=True) - subprocess.call(f'git tag v{version}', shell=True) - subprocess.call('git push', shell=True) - subprocess.call('git push --tags', shell=True) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser( - description=__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter - ) - parser.add_argument('version', help='Version number, e.g. 0.1.1') - - args = parser.parse_args() - - main(args.version) From d7e18bbb9bec27fbc8f1597c4188fbe128710321 Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Wed, 21 Dec 2022 12:43:22 +1100 Subject: [PATCH 02/12] Update gradle to newer version --- gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 61574 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 272 ++++++++++++++--------- gradlew.bat | 38 ++-- 4 files changed, 181 insertions(+), 132 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf016b3885f6930543d57b744ea8c220a1a..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644 GIT binary patch delta 41329 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
CzJPg&1&C#S}14UBT4n{?E;je=leIwEK80 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

y@x`+Tbra}}5^vb;M@BwAEuLYd4TN!#) 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 delta 35491 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 P+;zlAyf701baeg)J&AD9 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7c4388a9..f398c33c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 83f2acfd..65dcd68d 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,78 +17,113 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -105,84 +140,105 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 24467a14..6689b85b 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,10 +25,14 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @@ -37,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -51,7 +55,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -61,38 +65,26 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From 444e0006e3683884d2a0cd24b2af53031b203aed Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Wed, 21 Dec 2022 13:58:41 +1100 Subject: [PATCH 03/12] Rewrite build for Gradle 7.6 --- build.gradle | 44 ++++++++++++++++++++++++--------------- engine/build.gradle | 40 ++++++++++++++--------------------- example-bots/build.gradle | 23 +++++++------------- 3 files changed, 50 insertions(+), 57 deletions(-) diff --git a/build.gradle b/build.gradle index 216be097..78c8416b 100644 --- a/build.gradle +++ b/build.gradle @@ -27,32 +27,42 @@ if (project.hasProperty("release_version")) { configurations { scala + + engine { + transitive false + } + bots { + transitive false + } } repositories { - jcenter() + mavenCentral() } dependencies { scala group: 'org.scala-lang', name: 'scala-library', version: '2.11.7' scala group: 'org.scala-lang', name: 'scala-compiler', version: '2.11.7' scala group: 'org.scala-lang', name: 'scala-reflect', version: '2.11.7' + + engine project(":engine") + bots project(":example-bots") } -def serverJar = new File(project(":engine").libsDir, "engine.jar") +def serverJar = configurations.engine.singleFile task buildMap(type: JavaExec, dependsOn: [':engine:build']) { - main = 'battlecode.world.maps.' + project.property('buildMap') + mainClass = 'battlecode.world.maps.' + project.property('buildMap') classpath = files(serverJar) } task buildMaps(type: JavaExec, dependsOn: [':engine:build']) { - main = 'battlecode.world.BuildMaps' + mainClass = 'battlecode.world.BuildMaps' classpath = files(serverJar) } task headless(type: JavaExec, dependsOn: [':engine:build', ':example-bots:build']) { - main = 'battlecode.server.Main' + mainClass = 'battlecode.server.Main' classpath = files(serverJar) + project(':example-bots').sourceSets.main.output + configurations.scala args = ['-c=-'] jvmArgs = [ @@ -71,7 +81,7 @@ task headless(type: JavaExec, dependsOn: [':engine:build', ':example-bots:build' } task debug(type: JavaExec, dependsOn: [':engine:build', ':example-bots:build']) { - main = 'battlecode.server.Main' + mainClass = 'battlecode.server.Main' classpath = files(serverJar) + project(':example-bots').sourceSets.main.output + configurations.scala args = ['-c=-'] jvmArgs = [ @@ -91,7 +101,7 @@ task debug(type: JavaExec, dependsOn: [':engine:build', ':example-bots:build']) } task headlessX(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots:build']) { - main = 'battlecode.server.Main' + mainClass = 'battlecode.server.Main' classpath = files(serverJar) + project(':internal-test-bots').sourceSets.main.output + configurations.scala args = ['-c=-'] jvmArgs = [ @@ -110,7 +120,7 @@ task headlessX(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots } task debugX(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots:build']) { - main = 'battlecode.server.Main' + mainClass = 'battlecode.server.Main' classpath = files(serverJar) + project(':internal-test-bots').sourceSets.main.output + configurations.scala args = ['-c=-'] jvmArgs = [ @@ -131,7 +141,7 @@ task debugX(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots:bu task runFromClient(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots:build']) { - main = 'battlecode.server.Main' + mainClass = 'battlecode.server.Main' classpath = files(serverJar) + project(':internal-test-bots').sourceSets.main.output + configurations.scala args = ['-c=-'] jvmArgs = [ @@ -182,10 +192,10 @@ task release_main(type: Jar, dependsOn: [':engine:build']) { Files.write(f_version.toPath(), [project.property("release_version")]); } - baseName = "battlecode"; + archiveBaseName = "battlecode"; if (project.hasProperty("release_version")) version = project.property("release_version"); - destinationDir = project.projectDir; + destinationDirectory = project.projectDir; FileCollection src = files(f_version); src += zipTree(serverJar); @@ -203,10 +213,10 @@ task release_docs(type: Jar, dependsOn: [':engine:javadoc']) { throw new InvalidUserDataException("Must provide property \"release_version\"") } - baseName = "battlecode-javadoc" + archiveBaseName = "battlecode-javadoc" if (project.hasProperty("release_version")) version = project.property("release_version"); - destinationDir = project.projectDir; + destinationDirectory = project.projectDir; from new File(project(":engine").docsDir, "javadoc") } @@ -217,10 +227,10 @@ task release_docs_zip(type: Zip, dependsOn: [':engine:javadoc']) { throw new InvalidUserDataException("Must provide property \"release_version\"") } - baseName = "battlecode-javadoc" + archiveBaseName = "battlecode-javadoc" if (project.hasProperty("release_version")) version = project.property("release_version"); - destinationDir = project.projectDir; + destinationDirectory = project.projectDir; from new File(project(":engine").docsDir, "javadoc") } @@ -229,10 +239,10 @@ task release_sources(type: Jar, dependsOn: classes) { classifier = 'sources' from project(":engine").sourceSets.main.allSource - baseName = "battlecode-source" + archiveBaseName = "battlecode-source" if (project.hasProperty("release_version")) version = project.property("release_version"); - destinationDir = project.projectDir; + destinationDirectory = project.projectDir; // from new File(project(":engine").sourceDir, "source") } diff --git a/engine/build.gradle b/engine/build.gradle index 513140f3..70224bec 100644 --- a/engine/build.gradle +++ b/engine/build.gradle @@ -1,5 +1,3 @@ - - apply plugin: 'java' sourceCompatibility = 1.8 @@ -9,20 +7,19 @@ sourceSets { java.srcDirs = ["src/main"] resources.srcDirs = ["src/main"] - java.outputDir = file("$buildDir/classes") + java.destinationDirectory.set(file("$buildDir/classes")) output.resourcesDir = "$buildDir/classes" } test { java.srcDirs = ["src/test"] resources.srcDirs = ["src/test"] - java.outputDir = file("$buildDir/tests") + java.destinationDirectory.set(file("$buildDir/tests")) output.resourcesDir = "$buildDir/tests" } } repositories { - jcenter() mavenCentral() // Java Spatial Index for RTree maven {url "https://oss.sonatype.org/content/repositories/snapshots/"} @@ -30,46 +27,41 @@ repositories { } dependencies { - compile ( - [group: 'org.slf4j', name: 'slf4j-api', version: '1.7.21'], - [group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.21'], + implementation( + [group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'], + [group: 'commons-cli', name: 'commons-cli', version: '1.5.0'], + [group: 'commons-io', name: 'commons-io', version: '2.11.0'], - // normal dependencies - [group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'], - [group: 'commons-cli', name: 'commons-cli', version: '1.3.1'], - [group: 'commons-io', name: 'commons-io', version: '2.4'], [group: 'org.ow2.asm', name: 'asm', version: '5.0.4'], [group: 'org.ow2.asm', name: 'asm-tree', version: '5.0.4'], - + // Flatbuffers [group: 'com.google.flatbuffers', name: 'flatbuffers-java', version: '1.11.0'], // Websockets [group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.3.0'], - // we only use WeakIdentityHashMap which doesn't depend on anything - [group: 'org.hibernate', name: 'hibernate-search', version: '3.1.0.GA', transitive: false], + // We only use WeakIdentityHashMap which doesn't depend on anything + [group: 'org.hibernate', name: 'hibernate-search', version: '3.1.0.GA'], // Java Spatial Index, RTree indexing [group: 'net.sf.jsi', name: 'jsi', version: '1.1.0-SNAPSHOT'], [group: 'net.sf.trove4j', name: 'trove4j', version: '3.0.3'], + // Javadoc manipulation libraries + files(System.getenv('JAVA_HOME') + '/lib/tools.jar') ) - // Javadoc manipulation libraries - compile files(System.getenv('JAVA_HOME') + '/lib/tools.jar') - - // Testing dependencies - testCompile ( - [group: 'junit', name: 'junit', version: '4.12'], - [group: 'org.mockito', name: 'mockito-core', version: '1.10.19'], - [group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'] + testImplementation( + [group: 'junit', name: 'junit', version: '4.13.2'], + [group: 'org.mockito', name: 'mockito-core', version: '3.12.4'] ) } jar { + duplicatesStrategy 'exclude' from { - configurations.testCompile.collect { it.isDirectory() ? it : zipTree(it) } + configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) } } } diff --git a/example-bots/build.gradle b/example-bots/build.gradle index b1fcd065..168b9892 100644 --- a/example-bots/build.gradle +++ b/example-bots/build.gradle @@ -11,37 +11,28 @@ project.ext.release_players='NONE' repositories { mavenCentral() maven {url "https://oss.sonatype.org/content/repositories/snapshots/"} - jcenter() } sourceSets { main { scala.srcDirs = ["src/main"] - // output.classesDir = "$buildDir/classes" - java.outputDir = file("$buildDir/classes") - scala.outputDir = file("$buildDir/classes") + java.destinationDirectory.set(file("$buildDir/classes")) + scala.destinationDirectory.set(file("$buildDir/classes")) } test { scala.srcDirs = ["src/test"] - // output.classesDir = "$buildDir/tests" - java.outputDir = file("$buildDir/tests") - scala.outputDir = file("$buildDir/tests") + java.destinationDirectory.set(file("$buildDir/tests")) + scala.destinationDirectory.set(file("$buildDir/tests")) } - // main.java.srcDirs += 'src/main/kotlin' } dependencies { - compile project(':engine') + implementation project(':engine') + implementation group: 'org.scala-lang', name: 'scala3-library_3', version: '3.3.0-RC1-bin-20221219-0555491-NIGHTLY' - // scala - compile group: 'org.scala-lang', name: 'scala-library', version: '2.12.1' - - - - // Testing dependencies - testCompile 'junit:junit:4.12' + testImplementation group: 'junit', name: 'junit', version: '4.13.2' } jar { From 1a6ad6df99c15269f0d84486886554e12879a6c3 Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Wed, 21 Dec 2022 15:25:17 +1100 Subject: [PATCH 04/12] Delete legacy schema --- .../main/battlecode/schema-old/Action.java | 77 ----- .../main/battlecode/schema-old/BodyType.java | 34 --- .../schema-old/BodyTypeMetadata.java | 88 ------ .../src/main/battlecode/schema-old/Event.java | 44 --- .../battlecode/schema-old/EventWrapper.java | 40 --- .../battlecode/schema-old/GameFooter.java | 39 --- .../battlecode/schema-old/GameHeader.java | 63 ---- .../main/battlecode/schema-old/GameMap.java | 67 ----- .../battlecode/schema-old/GameWrapper.java | 72 ----- .../battlecode/schema-old/MatchFooter.java | 57 ---- .../battlecode/schema-old/MatchHeader.java | 47 --- .../battlecode/schema-old/ProfilerEvent.java | 57 ---- .../battlecode/schema-old/ProfilerFile.java | 54 ---- .../schema-old/ProfilerProfile.java | 52 ---- .../main/battlecode/schema-old/RGBTable.java | 59 ---- .../src/main/battlecode/schema-old/Round.java | 283 ------------------ .../schema-old/SpawnedBodyTable.java | 94 ------ .../main/battlecode/schema-old/TeamData.java | 57 ---- .../src/main/battlecode/schema-old/Vec.java | 29 -- .../main/battlecode/schema-old/VecTable.java | 50 ---- 20 files changed, 1363 deletions(-) delete mode 100644 engine/src/main/battlecode/schema-old/Action.java delete mode 100644 engine/src/main/battlecode/schema-old/BodyType.java delete mode 100644 engine/src/main/battlecode/schema-old/BodyTypeMetadata.java delete mode 100644 engine/src/main/battlecode/schema-old/Event.java delete mode 100644 engine/src/main/battlecode/schema-old/EventWrapper.java delete mode 100644 engine/src/main/battlecode/schema-old/GameFooter.java delete mode 100644 engine/src/main/battlecode/schema-old/GameHeader.java delete mode 100644 engine/src/main/battlecode/schema-old/GameMap.java delete mode 100644 engine/src/main/battlecode/schema-old/GameWrapper.java delete mode 100644 engine/src/main/battlecode/schema-old/MatchFooter.java delete mode 100644 engine/src/main/battlecode/schema-old/MatchHeader.java delete mode 100644 engine/src/main/battlecode/schema-old/ProfilerEvent.java delete mode 100644 engine/src/main/battlecode/schema-old/ProfilerFile.java delete mode 100644 engine/src/main/battlecode/schema-old/ProfilerProfile.java delete mode 100644 engine/src/main/battlecode/schema-old/RGBTable.java delete mode 100644 engine/src/main/battlecode/schema-old/Round.java delete mode 100644 engine/src/main/battlecode/schema-old/SpawnedBodyTable.java delete mode 100644 engine/src/main/battlecode/schema-old/TeamData.java delete mode 100644 engine/src/main/battlecode/schema-old/Vec.java delete mode 100644 engine/src/main/battlecode/schema-old/VecTable.java diff --git a/engine/src/main/battlecode/schema-old/Action.java b/engine/src/main/battlecode/schema-old/Action.java deleted file mode 100644 index ffd303b8..00000000 --- a/engine/src/main/battlecode/schema-old/Action.java +++ /dev/null @@ -1,77 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -/** - * Actions that can be performed. - * Purely aesthetic; have no actual effect on simulation. - * (Although the simulation may want to track the 'parents' of - * particular robots.) - * Actions may have 'targets', which are the units on which - * the actions were performed. - */ -public final class Action { - private Action() { } - /** - * Politicians self-destruct and affect nearby bodies. - * Target: radius squared - */ - public static final byte EMPOWER = 0; - /** - * Slanderers passively generate influence for the - * Enlightenment Center that created them. - * Target: parent ID - */ - public static final byte EMBEZZLE = 1; - /** - * Slanderers turn into Politicians. - * Target: none - */ - public static final byte CAMOUFLAGE = 2; - /** - * Muckrakers can expose a slanderer. - * Target: an enemy body - */ - public static final byte EXPOSE = 3; - /** - * Units can change their flag. - * Target: new flag value - */ - public static final byte SET_FLAG = 4; - /** - * Builds a unit. - * Target: spawned unit - */ - public static final byte SPAWN_UNIT = 5; - /** - * Places a bid. - * Target: bid value - */ - public static final byte PLACE_BID = 6; - /** - * A robot can change team after being empowered, - * or when a Enlightenment Center is taken over. - * Target: new robotID - */ - public static final byte CHANGE_TEAM = 7; - /** - * A robot's influence changes. - * Target: delta value - */ - public static final byte CHANGE_INFLUENCE = 8; - /** - * A robot's conviction changes. - * Target: delta value, i.e. red 5 -> blue 3 is -2 - */ - public static final byte CHANGE_CONVICTION = 9; - /** - * Dies due to an uncaught exception. - * Target: none - */ - public static final byte DIE_EXCEPTION = 10; - - public static final String[] names = { "EMPOWER", "EMBEZZLE", "CAMOUFLAGE", "EXPOSE", "SET_FLAG", "SPAWN_UNIT", "PLACE_BID", "CHANGE_TEAM", "CHANGE_INFLUENCE", "CHANGE_CONVICTION", "DIE_EXCEPTION", }; - - public static String name(int e) { return names[e]; } -} - diff --git a/engine/src/main/battlecode/schema-old/BodyType.java b/engine/src/main/battlecode/schema-old/BodyType.java deleted file mode 100644 index 2d4ae7ab..00000000 --- a/engine/src/main/battlecode/schema-old/BodyType.java +++ /dev/null @@ -1,34 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -/** - * The possible types of things that can exist. - * Note that bullets are not treated as bodies. - */ -public final class BodyType { - private BodyType() { } - /** - * Enlightenment centers produce politicians, Muckrakers and slanderers and place bids - *can be neutral until captured - */ - public static final byte ENLIGHTENMENT_CENTER = 0; - /** - * politicians use their influence to self destruct and capture other units - */ - public static final byte POLITICIAN = 1; - /** - * slanderers generate passive influence for the enlightenment center that created them - * they turn into politicians at some point, and can only be identified by slanderers. - */ - public static final byte SLANDERER = 2; - /** - * have the ability to identify slanderers - */ - public static final byte MUCKRAKER = 3; - - public static final String[] names = { "ENLIGHTENMENT_CENTER", "POLITICIAN", "SLANDERER", "MUCKRAKER", }; - - public static String name(int e) { return names[e]; } -} - diff --git a/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java b/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java deleted file mode 100644 index a2825c7c..00000000 --- a/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java +++ /dev/null @@ -1,88 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * Metadata about all bodies of a particular type. - */ -public final class BodyTypeMetadata extends Table { - public static BodyTypeMetadata getRootAsBodyTypeMetadata(ByteBuffer _bb) { return getRootAsBodyTypeMetadata(_bb, new BodyTypeMetadata()); } - public static BodyTypeMetadata getRootAsBodyTypeMetadata(ByteBuffer _bb, BodyTypeMetadata obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public BodyTypeMetadata __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The relevant type. - */ - public byte type() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * The spawn source. - */ - public byte spawnSource() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * the convictionRatio of this type - */ - public float convictionRatio() { int o = __offset(8); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } - /** - * cooldown of this type - */ - public float actionCooldown() { int o = __offset(10); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } - /** - * action radius if this type - */ - public int actionRadiusSquared() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * sensor radius squared for this type - */ - public int sensorRadiusSquared() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * detection radius of this type - */ - public int detectionRadiusSquared() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * bytecode limit for this type - */ - public int bytecodeLimit() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - - public static int createBodyTypeMetadata(FlatBufferBuilder builder, - byte type, - byte spawnSource, - float convictionRatio, - float actionCooldown, - int actionRadiusSquared, - int sensorRadiusSquared, - int detectionRadiusSquared, - int bytecodeLimit) { - builder.startObject(8); - BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addDetectionRadiusSquared(builder, detectionRadiusSquared); - BodyTypeMetadata.addSensorRadiusSquared(builder, sensorRadiusSquared); - BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); - BodyTypeMetadata.addActionCooldown(builder, actionCooldown); - BodyTypeMetadata.addConvictionRatio(builder, convictionRatio); - BodyTypeMetadata.addSpawnSource(builder, spawnSource); - BodyTypeMetadata.addType(builder, type); - return BodyTypeMetadata.endBodyTypeMetadata(builder); - } - - public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(8); } - public static void addType(FlatBufferBuilder builder, byte type) { builder.addByte(0, type, 0); } - public static void addSpawnSource(FlatBufferBuilder builder, byte spawnSource) { builder.addByte(1, spawnSource, 0); } - public static void addConvictionRatio(FlatBufferBuilder builder, float convictionRatio) { builder.addFloat(2, convictionRatio, 0.0f); } - public static void addActionCooldown(FlatBufferBuilder builder, float actionCooldown) { builder.addFloat(3, actionCooldown, 0.0f); } - public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(4, actionRadiusSquared, 0); } - public static void addSensorRadiusSquared(FlatBufferBuilder builder, int sensorRadiusSquared) { builder.addInt(5, sensorRadiusSquared, 0); } - public static void addDetectionRadiusSquared(FlatBufferBuilder builder, int detectionRadiusSquared) { builder.addInt(6, detectionRadiusSquared, 0); } - public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(7, bytecodeLimit, 0); } - public static int endBodyTypeMetadata(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/Event.java b/engine/src/main/battlecode/schema-old/Event.java deleted file mode 100644 index ccfb7cd9..00000000 --- a/engine/src/main/battlecode/schema-old/Event.java +++ /dev/null @@ -1,44 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -/** - * Events - * An Event is a single step that needs to be processed. - * A saved game simply consists of a long list of Events. - * Events can be divided by either being sent separately (e.g. as separate - * websocket messages), or by being wrapped with a GameWrapper. - * A game consists of a series of matches; a match consists of a series of - * rounds, and is played on a single map. Each round is a single simulation - * step. - */ -public final class Event { - private Event() { } - public static final byte NONE = 0; - /** - * There should only be one GameHeader, at the start of the stream. - */ - public static final byte GameHeader = 1; - /** - * There should be one MatchHeader at the start of each match. - */ - public static final byte MatchHeader = 2; - /** - * A single simulation step. A round may be skipped if - * nothing happens during its time. - */ - public static final byte Round = 3; - /** - * There should be one MatchFooter at the end of each simulation step. - */ - public static final byte MatchFooter = 4; - /** - * There should only be one GameFooter, at the end of the stream. - */ - public static final byte GameFooter = 5; - - public static final String[] names = { "NONE", "GameHeader", "MatchHeader", "Round", "MatchFooter", "GameFooter", }; - - public static String name(int e) { return names[e]; } -} - diff --git a/engine/src/main/battlecode/schema-old/EventWrapper.java b/engine/src/main/battlecode/schema-old/EventWrapper.java deleted file mode 100644 index d3377ac7..00000000 --- a/engine/src/main/battlecode/schema-old/EventWrapper.java +++ /dev/null @@ -1,40 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * Necessary due to flatbuffers requiring unions to be wrapped in tables. - */ -public final class EventWrapper extends Table { - public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb) { return getRootAsEventWrapper(_bb, new EventWrapper()); } - public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb, EventWrapper obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public EventWrapper __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - public byte eType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - public Table e(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; } - - public static int createEventWrapper(FlatBufferBuilder builder, - byte e_type, - int eOffset) { - builder.startObject(2); - EventWrapper.addE(builder, eOffset); - EventWrapper.addEType(builder, e_type); - return EventWrapper.endEventWrapper(builder); - } - - public static void startEventWrapper(FlatBufferBuilder builder) { builder.startObject(2); } - public static void addEType(FlatBufferBuilder builder, byte eType) { builder.addByte(0, eType, 0); } - public static void addE(FlatBufferBuilder builder, int eOffset) { builder.addOffset(1, eOffset, 0); } - public static int endEventWrapper(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/GameFooter.java b/engine/src/main/battlecode/schema-old/GameFooter.java deleted file mode 100644 index 70bab946..00000000 --- a/engine/src/main/battlecode/schema-old/GameFooter.java +++ /dev/null @@ -1,39 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * The final event sent in the game. - */ -public final class GameFooter extends Table { - public static GameFooter getRootAsGameFooter(ByteBuffer _bb) { return getRootAsGameFooter(_bb, new GameFooter()); } - public static GameFooter getRootAsGameFooter(ByteBuffer _bb, GameFooter obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public GameFooter __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The ID of the winning team of the game. - */ - public byte winner() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - - public static int createGameFooter(FlatBufferBuilder builder, - byte winner) { - builder.startObject(1); - GameFooter.addWinner(builder, winner); - return GameFooter.endGameFooter(builder); - } - - public static void startGameFooter(FlatBufferBuilder builder) { builder.startObject(1); } - public static void addWinner(FlatBufferBuilder builder, byte winner) { builder.addByte(0, winner, 0); } - public static int endGameFooter(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/GameHeader.java b/engine/src/main/battlecode/schema-old/GameHeader.java deleted file mode 100644 index 53b7e653..00000000 --- a/engine/src/main/battlecode/schema-old/GameHeader.java +++ /dev/null @@ -1,63 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * The first event sent in the game. Contains all metadata about the game. - */ -public final class GameHeader extends Table { - public static GameHeader getRootAsGameHeader(ByteBuffer _bb) { return getRootAsGameHeader(_bb, new GameHeader()); } - public static GameHeader getRootAsGameHeader(ByteBuffer _bb, GameHeader obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public GameHeader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The version of the spec this game complies with. - */ - public String specVersion() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer specVersionAsByteBuffer() { return __vector_as_bytebuffer(4, 1); } - public ByteBuffer specVersionInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); } - /** - * The teams participating in the game. - */ - public TeamData teams(int j) { return teams(new TeamData(), j); } - public TeamData teams(TeamData obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } - public int teamsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - /** - * Information about all body types in the game. - */ - public BodyTypeMetadata bodyTypeMetadata(int j) { return bodyTypeMetadata(new BodyTypeMetadata(), j); } - public BodyTypeMetadata bodyTypeMetadata(BodyTypeMetadata obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } - public int bodyTypeMetadataLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - - public static int createGameHeader(FlatBufferBuilder builder, - int specVersionOffset, - int teamsOffset, - int bodyTypeMetadataOffset) { - builder.startObject(3); - GameHeader.addBodyTypeMetadata(builder, bodyTypeMetadataOffset); - GameHeader.addTeams(builder, teamsOffset); - GameHeader.addSpecVersion(builder, specVersionOffset); - return GameHeader.endGameHeader(builder); - } - - public static void startGameHeader(FlatBufferBuilder builder) { builder.startObject(3); } - public static void addSpecVersion(FlatBufferBuilder builder, int specVersionOffset) { builder.addOffset(0, specVersionOffset, 0); } - public static void addTeams(FlatBufferBuilder builder, int teamsOffset) { builder.addOffset(1, teamsOffset, 0); } - public static int createTeamsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } - public static void startTeamsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addBodyTypeMetadata(FlatBufferBuilder builder, int bodyTypeMetadataOffset) { builder.addOffset(2, bodyTypeMetadataOffset, 0); } - public static int createBodyTypeMetadataVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } - public static void startBodyTypeMetadataVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endGameHeader(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/GameMap.java b/engine/src/main/battlecode/schema-old/GameMap.java deleted file mode 100644 index 34475b23..00000000 --- a/engine/src/main/battlecode/schema-old/GameMap.java +++ /dev/null @@ -1,67 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * The map a round is played on. - */ -public final class GameMap extends Table { - public static GameMap getRootAsGameMap(ByteBuffer _bb) { return getRootAsGameMap(_bb, new GameMap()); } - public static GameMap getRootAsGameMap(ByteBuffer _bb, GameMap obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public GameMap __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The name of a map. - */ - public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); } - public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); } - /** - * The bottom corner of the map. - */ - public Vec minCorner() { return minCorner(new Vec()); } - public Vec minCorner(Vec obj) { int o = __offset(6); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } - /** - * The top corner of the map. - */ - public Vec maxCorner() { return maxCorner(new Vec()); } - public Vec maxCorner(Vec obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } - /** - * The bodies on the map. - */ - public SpawnedBodyTable bodies() { return bodies(new SpawnedBodyTable()); } - public SpawnedBodyTable bodies(SpawnedBodyTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * The random seed of the map. - */ - public int randomSeed() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * The factor to divide cooldowns by - */ - public double passability(int j) { int o = __offset(14); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; } - public int passabilityLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer passabilityAsByteBuffer() { return __vector_as_bytebuffer(14, 8); } - public ByteBuffer passabilityInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 8); } - - public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(6); } - public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } - public static void addMinCorner(FlatBufferBuilder builder, int minCornerOffset) { builder.addStruct(1, minCornerOffset, 0); } - public static void addMaxCorner(FlatBufferBuilder builder, int maxCornerOffset) { builder.addStruct(2, maxCornerOffset, 0); } - public static void addBodies(FlatBufferBuilder builder, int bodiesOffset) { builder.addOffset(3, bodiesOffset, 0); } - public static void addRandomSeed(FlatBufferBuilder builder, int randomSeed) { builder.addInt(4, randomSeed, 0); } - public static void addPassability(FlatBufferBuilder builder, int passabilityOffset) { builder.addOffset(5, passabilityOffset, 0); } - public static int createPassabilityVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); } - public static void startPassabilityVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); } - public static int endGameMap(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/GameWrapper.java b/engine/src/main/battlecode/schema-old/GameWrapper.java deleted file mode 100644 index ecf4634c..00000000 --- a/engine/src/main/battlecode/schema-old/GameWrapper.java +++ /dev/null @@ -1,72 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * If events are not otherwise delimited, this wrapper structure - * allows a game to be stored in a single buffer. - * The first event will be a GameHeader; the last event will be a GameFooter. - * matchHeaders[0] is the index of the 0th match header in the event stream, - * corresponding to matchFooters[0]. These indices allow quick traversal of - * the file. - */ -public final class GameWrapper extends Table { - public static GameWrapper getRootAsGameWrapper(ByteBuffer _bb) { return getRootAsGameWrapper(_bb, new GameWrapper()); } - public static GameWrapper getRootAsGameWrapper(ByteBuffer _bb, GameWrapper obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public GameWrapper __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The series of events comprising the game. - */ - public EventWrapper events(int j) { return events(new EventWrapper(), j); } - public EventWrapper events(EventWrapper obj, int j) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } - public int eventsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } - /** - * The indices of the headers of the matches, in order. - */ - public int matchHeaders(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int matchHeadersLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer matchHeadersAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } - public ByteBuffer matchHeadersInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } - /** - * The indices of the footers of the matches, in order. - */ - public int matchFooters(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int matchFootersLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer matchFootersAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } - public ByteBuffer matchFootersInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } - - public static int createGameWrapper(FlatBufferBuilder builder, - int eventsOffset, - int matchHeadersOffset, - int matchFootersOffset) { - builder.startObject(3); - GameWrapper.addMatchFooters(builder, matchFootersOffset); - GameWrapper.addMatchHeaders(builder, matchHeadersOffset); - GameWrapper.addEvents(builder, eventsOffset); - return GameWrapper.endGameWrapper(builder); - } - - public static void startGameWrapper(FlatBufferBuilder builder) { builder.startObject(3); } - public static void addEvents(FlatBufferBuilder builder, int eventsOffset) { builder.addOffset(0, eventsOffset, 0); } - public static int createEventsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } - public static void startEventsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addMatchHeaders(FlatBufferBuilder builder, int matchHeadersOffset) { builder.addOffset(1, matchHeadersOffset, 0); } - public static int createMatchHeadersVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startMatchHeadersVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addMatchFooters(FlatBufferBuilder builder, int matchFootersOffset) { builder.addOffset(2, matchFootersOffset, 0); } - public static int createMatchFootersVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startMatchFootersVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endGameWrapper(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/MatchFooter.java b/engine/src/main/battlecode/schema-old/MatchFooter.java deleted file mode 100644 index 74fa1fd1..00000000 --- a/engine/src/main/battlecode/schema-old/MatchFooter.java +++ /dev/null @@ -1,57 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * Sent to end a match. - */ -public final class MatchFooter extends Table { - public static MatchFooter getRootAsMatchFooter(ByteBuffer _bb) { return getRootAsMatchFooter(_bb, new MatchFooter()); } - public static MatchFooter getRootAsMatchFooter(ByteBuffer _bb, MatchFooter obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public MatchFooter __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The ID of the winning team. - */ - public byte winner() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * The number of rounds played. - */ - public int totalRounds() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * Profiler data for team A and B if profiling is enabled. - */ - public ProfilerFile profilerFiles(int j) { return profilerFiles(new ProfilerFile(), j); } - public ProfilerFile profilerFiles(ProfilerFile obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } - public int profilerFilesLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - - public static int createMatchFooter(FlatBufferBuilder builder, - byte winner, - int totalRounds, - int profilerFilesOffset) { - builder.startObject(3); - MatchFooter.addProfilerFiles(builder, profilerFilesOffset); - MatchFooter.addTotalRounds(builder, totalRounds); - MatchFooter.addWinner(builder, winner); - return MatchFooter.endMatchFooter(builder); - } - - public static void startMatchFooter(FlatBufferBuilder builder) { builder.startObject(3); } - public static void addWinner(FlatBufferBuilder builder, byte winner) { builder.addByte(0, winner, 0); } - public static void addTotalRounds(FlatBufferBuilder builder, int totalRounds) { builder.addInt(1, totalRounds, 0); } - public static void addProfilerFiles(FlatBufferBuilder builder, int profilerFilesOffset) { builder.addOffset(2, profilerFilesOffset, 0); } - public static int createProfilerFilesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } - public static void startProfilerFilesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endMatchFooter(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/MatchHeader.java b/engine/src/main/battlecode/schema-old/MatchHeader.java deleted file mode 100644 index ec5a46d0..00000000 --- a/engine/src/main/battlecode/schema-old/MatchHeader.java +++ /dev/null @@ -1,47 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * Sent to start a match. - */ -public final class MatchHeader extends Table { - public static MatchHeader getRootAsMatchHeader(ByteBuffer _bb) { return getRootAsMatchHeader(_bb, new MatchHeader()); } - public static MatchHeader getRootAsMatchHeader(ByteBuffer _bb, MatchHeader obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public MatchHeader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The map the match was played on. - */ - public GameMap map() { return map(new GameMap()); } - public GameMap map(GameMap obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * The maximum number of rounds in this match. - */ - public int maxRounds() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - - public static int createMatchHeader(FlatBufferBuilder builder, - int mapOffset, - int maxRounds) { - builder.startObject(2); - MatchHeader.addMaxRounds(builder, maxRounds); - MatchHeader.addMap(builder, mapOffset); - return MatchHeader.endMatchHeader(builder); - } - - public static void startMatchHeader(FlatBufferBuilder builder) { builder.startObject(2); } - public static void addMap(FlatBufferBuilder builder, int mapOffset) { builder.addOffset(0, mapOffset, 0); } - public static void addMaxRounds(FlatBufferBuilder builder, int maxRounds) { builder.addInt(1, maxRounds, 0); } - public static int endMatchHeader(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/ProfilerEvent.java b/engine/src/main/battlecode/schema-old/ProfilerEvent.java deleted file mode 100644 index 0fbcd553..00000000 --- a/engine/src/main/battlecode/schema-old/ProfilerEvent.java +++ /dev/null @@ -1,57 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * These tables are set-up so that they match closely with speedscope's file format documented at - * https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. - * The client uses speedscope to show the recorded data in an interactive interface. - * A single event in a profile. Represents either an open event (meaning a - * method has been entered) or a close event (meaning the method was exited). - */ -public final class ProfilerEvent extends Table { - public static ProfilerEvent getRootAsProfilerEvent(ByteBuffer _bb) { return getRootAsProfilerEvent(_bb, new ProfilerEvent()); } - public static ProfilerEvent getRootAsProfilerEvent(ByteBuffer _bb, ProfilerEvent obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public ProfilerEvent __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * Whether this is an open event (true) or a close event (false). - */ - public boolean isOpen() { int o = __offset(4); return o != 0 ? 0!=bb.get(o + bb_pos) : false; } - /** - * The bytecode counter at the time the event occurred. - */ - public int at() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * The index of the method name in the ProfilerFile.frames array. - */ - public int frame() { int o = __offset(8); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - - public static int createProfilerEvent(FlatBufferBuilder builder, - boolean isOpen, - int at, - int frame) { - builder.startObject(3); - ProfilerEvent.addFrame(builder, frame); - ProfilerEvent.addAt(builder, at); - ProfilerEvent.addIsOpen(builder, isOpen); - return ProfilerEvent.endProfilerEvent(builder); - } - - public static void startProfilerEvent(FlatBufferBuilder builder) { builder.startObject(3); } - public static void addIsOpen(FlatBufferBuilder builder, boolean isOpen) { builder.addBoolean(0, isOpen, false); } - public static void addAt(FlatBufferBuilder builder, int at) { builder.addInt(1, at, 0); } - public static void addFrame(FlatBufferBuilder builder, int frame) { builder.addInt(2, frame, 0); } - public static int endProfilerEvent(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/ProfilerFile.java b/engine/src/main/battlecode/schema-old/ProfilerFile.java deleted file mode 100644 index ffbd5e0d..00000000 --- a/engine/src/main/battlecode/schema-old/ProfilerFile.java +++ /dev/null @@ -1,54 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * A profiler file is a collection of profiles. - * When profiling is enabled there is one of these per team per match. - */ -public final class ProfilerFile extends Table { - public static ProfilerFile getRootAsProfilerFile(ByteBuffer _bb) { return getRootAsProfilerFile(_bb, new ProfilerFile()); } - public static ProfilerFile getRootAsProfilerFile(ByteBuffer _bb, ProfilerFile obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public ProfilerFile __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The method names that are referred to in the events. - */ - public String frames(int j) { int o = __offset(4); return o != 0 ? __string(__vector(o) + j * 4) : null; } - public int framesLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } - /** - * The recorded profiles, one per robot. - */ - public ProfilerProfile profiles(int j) { return profiles(new ProfilerProfile(), j); } - public ProfilerProfile profiles(ProfilerProfile obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } - public int profilesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - - public static int createProfilerFile(FlatBufferBuilder builder, - int framesOffset, - int profilesOffset) { - builder.startObject(2); - ProfilerFile.addProfiles(builder, profilesOffset); - ProfilerFile.addFrames(builder, framesOffset); - return ProfilerFile.endProfilerFile(builder); - } - - public static void startProfilerFile(FlatBufferBuilder builder) { builder.startObject(2); } - public static void addFrames(FlatBufferBuilder builder, int framesOffset) { builder.addOffset(0, framesOffset, 0); } - public static int createFramesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } - public static void startFramesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addProfiles(FlatBufferBuilder builder, int profilesOffset) { builder.addOffset(1, profilesOffset, 0); } - public static int createProfilesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } - public static void startProfilesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endProfilerFile(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/ProfilerProfile.java b/engine/src/main/battlecode/schema-old/ProfilerProfile.java deleted file mode 100644 index 34a12924..00000000 --- a/engine/src/main/battlecode/schema-old/ProfilerProfile.java +++ /dev/null @@ -1,52 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * A profile contains all events and is labeled with a name. - */ -public final class ProfilerProfile extends Table { - public static ProfilerProfile getRootAsProfilerProfile(ByteBuffer _bb) { return getRootAsProfilerProfile(_bb, new ProfilerProfile()); } - public static ProfilerProfile getRootAsProfilerProfile(ByteBuffer _bb, ProfilerProfile obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public ProfilerProfile __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The display-friendly name of the profile. - */ - public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); } - public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); } - /** - * The events that occurred in the profile. - */ - public ProfilerEvent events(int j) { return events(new ProfilerEvent(), j); } - public ProfilerEvent events(ProfilerEvent obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } - public int eventsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - - public static int createProfilerProfile(FlatBufferBuilder builder, - int nameOffset, - int eventsOffset) { - builder.startObject(2); - ProfilerProfile.addEvents(builder, eventsOffset); - ProfilerProfile.addName(builder, nameOffset); - return ProfilerProfile.endProfilerProfile(builder); - } - - public static void startProfilerProfile(FlatBufferBuilder builder) { builder.startObject(2); } - public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } - public static void addEvents(FlatBufferBuilder builder, int eventsOffset) { builder.addOffset(1, eventsOffset, 0); } - public static int createEventsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } - public static void startEventsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endProfilerProfile(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/RGBTable.java b/engine/src/main/battlecode/schema-old/RGBTable.java deleted file mode 100644 index 96fdeb9c..00000000 --- a/engine/src/main/battlecode/schema-old/RGBTable.java +++ /dev/null @@ -1,59 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * A table of RGB values. - */ -public final class RGBTable extends Table { - public static RGBTable getRootAsRGBTable(ByteBuffer _bb) { return getRootAsRGBTable(_bb, new RGBTable()); } - public static RGBTable getRootAsRGBTable(ByteBuffer _bb, RGBTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public RGBTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - public int red(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int redLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer redAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } - public ByteBuffer redInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } - public int green(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int greenLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer greenAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } - public ByteBuffer greenInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } - public int blue(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int blueLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer blueAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } - public ByteBuffer blueInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } - - public static int createRGBTable(FlatBufferBuilder builder, - int redOffset, - int greenOffset, - int blueOffset) { - builder.startObject(3); - RGBTable.addBlue(builder, blueOffset); - RGBTable.addGreen(builder, greenOffset); - RGBTable.addRed(builder, redOffset); - return RGBTable.endRGBTable(builder); - } - - public static void startRGBTable(FlatBufferBuilder builder) { builder.startObject(3); } - public static void addRed(FlatBufferBuilder builder, int redOffset) { builder.addOffset(0, redOffset, 0); } - public static int createRedVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startRedVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addGreen(FlatBufferBuilder builder, int greenOffset) { builder.addOffset(1, greenOffset, 0); } - public static int createGreenVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startGreenVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addBlue(FlatBufferBuilder builder, int blueOffset) { builder.addOffset(2, blueOffset, 0); } - public static int createBlueVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startBlueVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endRGBTable(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/Round.java b/engine/src/main/battlecode/schema-old/Round.java deleted file mode 100644 index c45ebc4e..00000000 --- a/engine/src/main/battlecode/schema-old/Round.java +++ /dev/null @@ -1,283 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * A single time-step in a Game. - * The bulk of the data in the file is stored in tables like this. - * Note that a struct-of-arrays format is more space efficient than an array- - * of-structs. - */ -public final class Round extends Table { - public static Round getRootAsRound(ByteBuffer _bb) { return getRootAsRound(_bb, new Round()); } - public static Round getRootAsRound(ByteBuffer _bb, Round obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public Round __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The IDs of teams in the Game. - */ - public int teamIDs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamIDsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamIDsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } - public ByteBuffer teamIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } - /** - * The number of votes the teams get, 0 or 1. - */ - public int teamVotes(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamVotesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamVotesAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } - public ByteBuffer teamVotesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } - /** - * The ID of the Enlightenment Center got the bid. - */ - public int teamBidderIDs(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamBidderIDsLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamBidderIDsAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } - public ByteBuffer teamBidderIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } - /** - * The IDs of bodies that moved. - */ - public int movedIDs(int j) { int o = __offset(10); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int movedIDsLength() { int o = __offset(10); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer movedIDsAsByteBuffer() { return __vector_as_bytebuffer(10, 4); } - public ByteBuffer movedIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 4); } - /** - * The new locations of bodies that have moved. - */ - public VecTable movedLocs() { return movedLocs(new VecTable()); } - public VecTable movedLocs(VecTable obj) { int o = __offset(12); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * New bodies. - */ - public SpawnedBodyTable spawnedBodies() { return spawnedBodies(new SpawnedBodyTable()); } - public SpawnedBodyTable spawnedBodies(SpawnedBodyTable obj) { int o = __offset(14); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * The IDs of bodies that died. - */ - public int diedIDs(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int diedIDsLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer diedIDsAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } - public ByteBuffer diedIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } - /** - * The IDs of robots that performed actions. - * IDs may repeat. - */ - public int actionIDs(int j) { int o = __offset(18); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int actionIDsLength() { int o = __offset(18); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer actionIDsAsByteBuffer() { return __vector_as_bytebuffer(18, 4); } - public ByteBuffer actionIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 18, 4); } - /** - * The actions performed. These actions allow us to track how much soup or dirt a body carries. - */ - public byte actions(int j) { int o = __offset(20); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } - public int actionsLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer actionsAsByteBuffer() { return __vector_as_bytebuffer(20, 1); } - public ByteBuffer actionsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 1); } - /** - * The 'targets' of the performed actions. Actions without targets may have any value - */ - public int actionTargets(int j) { int o = __offset(22); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int actionTargetsLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer actionTargetsAsByteBuffer() { return __vector_as_bytebuffer(22, 4); } - public ByteBuffer actionTargetsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); } - /** - * The IDs of bodies that set indicator dots - */ - public int indicatorDotIDs(int j) { int o = __offset(24); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int indicatorDotIDsLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer indicatorDotIDsAsByteBuffer() { return __vector_as_bytebuffer(24, 4); } - public ByteBuffer indicatorDotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 4); } - /** - * The location of the indicator dots - */ - public VecTable indicatorDotLocs() { return indicatorDotLocs(new VecTable()); } - public VecTable indicatorDotLocs(VecTable obj) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * The RGB values of the indicator dots - */ - public RGBTable indicatorDotRGBs() { return indicatorDotRGBs(new RGBTable()); } - public RGBTable indicatorDotRGBs(RGBTable obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * The IDs of bodies that set indicator lines - */ - public int indicatorLineIDs(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int indicatorLineIDsLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer indicatorLineIDsAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } - public ByteBuffer indicatorLineIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } - /** - * The start location of the indicator lines - */ - public VecTable indicatorLineStartLocs() { return indicatorLineStartLocs(new VecTable()); } - public VecTable indicatorLineStartLocs(VecTable obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * The end location of the indicator lines - */ - public VecTable indicatorLineEndLocs() { return indicatorLineEndLocs(new VecTable()); } - public VecTable indicatorLineEndLocs(VecTable obj) { int o = __offset(34); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * The RGB values of the indicator lines - */ - public RGBTable indicatorLineRGBs() { return indicatorLineRGBs(new RGBTable()); } - public RGBTable indicatorLineRGBs(RGBTable obj) { int o = __offset(36); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * All logs sent this round. - * Messages from a particular robot in this round start on a new line, and - * have a header: - * '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - * $TEAM = 'A' | 'B' - * $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - * $ID = a number - * $ROUND = a number - * The header is not necessarily followed by a newline. - * This header should only be sent once per robot per round (although - * players may forge it, so don't crash if you get strange input.) - * - * You should try to only read this value once, and cache it. Reading - * strings from a flatbuffer is much less efficient than reading other - * buffers, because they need to be copied into an environment-provided - * buffer and validated. - * - * (haha i guess you can never really escape string parsing can you) - */ - public String logs() { int o = __offset(38); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer logsAsByteBuffer() { return __vector_as_bytebuffer(38, 1); } - public ByteBuffer logsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 38, 1); } - /** - * The first sent Round in a match should have index 1. (The starting state, - * created by the MatchHeader, can be thought to have index 0.) - * It should increase by one for each following round. - */ - public int roundID() { int o = __offset(40); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * The IDs of player bodies. - */ - public int bytecodeIDs(int j) { int o = __offset(42); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int bytecodeIDsLength() { int o = __offset(42); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer bytecodeIDsAsByteBuffer() { return __vector_as_bytebuffer(42, 4); } - public ByteBuffer bytecodeIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 42, 4); } - /** - * The bytecodes used by the player bodies. - */ - public int bytecodesUsed(int j) { int o = __offset(44); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int bytecodesUsedLength() { int o = __offset(44); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer bytecodesUsedAsByteBuffer() { return __vector_as_bytebuffer(44, 4); } - public ByteBuffer bytecodesUsedInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 44, 4); } - /** - * Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. - */ - public int teamNumBuffs(int j) { int o = __offset(46); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamNumBuffsLength() { int o = __offset(46); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamNumBuffsAsByteBuffer() { return __vector_as_bytebuffer(46, 4); } - public ByteBuffer teamNumBuffsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 46, 4); } - - public static int createRound(FlatBufferBuilder builder, - int teamIDsOffset, - int teamVotesOffset, - int teamBidderIDsOffset, - int movedIDsOffset, - int movedLocsOffset, - int spawnedBodiesOffset, - int diedIDsOffset, - int actionIDsOffset, - int actionsOffset, - int actionTargetsOffset, - int indicatorDotIDsOffset, - int indicatorDotLocsOffset, - int indicatorDotRGBsOffset, - int indicatorLineIDsOffset, - int indicatorLineStartLocsOffset, - int indicatorLineEndLocsOffset, - int indicatorLineRGBsOffset, - int logsOffset, - int roundID, - int bytecodeIDsOffset, - int bytecodesUsedOffset, - int teamNumBuffsOffset) { - builder.startObject(22); - Round.addTeamNumBuffs(builder, teamNumBuffsOffset); - Round.addBytecodesUsed(builder, bytecodesUsedOffset); - Round.addBytecodeIDs(builder, bytecodeIDsOffset); - Round.addRoundID(builder, roundID); - Round.addLogs(builder, logsOffset); - Round.addIndicatorLineRGBs(builder, indicatorLineRGBsOffset); - Round.addIndicatorLineEndLocs(builder, indicatorLineEndLocsOffset); - Round.addIndicatorLineStartLocs(builder, indicatorLineStartLocsOffset); - Round.addIndicatorLineIDs(builder, indicatorLineIDsOffset); - Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); - Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); - Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); - Round.addActionTargets(builder, actionTargetsOffset); - Round.addActions(builder, actionsOffset); - Round.addActionIDs(builder, actionIDsOffset); - Round.addDiedIDs(builder, diedIDsOffset); - Round.addSpawnedBodies(builder, spawnedBodiesOffset); - Round.addMovedLocs(builder, movedLocsOffset); - Round.addMovedIDs(builder, movedIDsOffset); - Round.addTeamBidderIDs(builder, teamBidderIDsOffset); - Round.addTeamVotes(builder, teamVotesOffset); - Round.addTeamIDs(builder, teamIDsOffset); - return Round.endRound(builder); - } - - public static void startRound(FlatBufferBuilder builder) { builder.startObject(22); } - public static void addTeamIDs(FlatBufferBuilder builder, int teamIDsOffset) { builder.addOffset(0, teamIDsOffset, 0); } - public static int createTeamIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamVotes(FlatBufferBuilder builder, int teamVotesOffset) { builder.addOffset(1, teamVotesOffset, 0); } - public static int createTeamVotesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamVotesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamBidderIDs(FlatBufferBuilder builder, int teamBidderIDsOffset) { builder.addOffset(2, teamBidderIDsOffset, 0); } - public static int createTeamBidderIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamBidderIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addMovedIDs(FlatBufferBuilder builder, int movedIDsOffset) { builder.addOffset(3, movedIDsOffset, 0); } - public static int createMovedIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startMovedIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addMovedLocs(FlatBufferBuilder builder, int movedLocsOffset) { builder.addOffset(4, movedLocsOffset, 0); } - public static void addSpawnedBodies(FlatBufferBuilder builder, int spawnedBodiesOffset) { builder.addOffset(5, spawnedBodiesOffset, 0); } - public static void addDiedIDs(FlatBufferBuilder builder, int diedIDsOffset) { builder.addOffset(6, diedIDsOffset, 0); } - public static int createDiedIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startDiedIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addActionIDs(FlatBufferBuilder builder, int actionIDsOffset) { builder.addOffset(7, actionIDsOffset, 0); } - public static int createActionIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startActionIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addActions(FlatBufferBuilder builder, int actionsOffset) { builder.addOffset(8, actionsOffset, 0); } - public static int createActionsVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } - public static void startActionsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } - public static void addActionTargets(FlatBufferBuilder builder, int actionTargetsOffset) { builder.addOffset(9, actionTargetsOffset, 0); } - public static int createActionTargetsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startActionTargetsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorDotIDs(FlatBufferBuilder builder, int indicatorDotIDsOffset) { builder.addOffset(10, indicatorDotIDsOffset, 0); } - public static int createIndicatorDotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startIndicatorDotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorDotLocs(FlatBufferBuilder builder, int indicatorDotLocsOffset) { builder.addOffset(11, indicatorDotLocsOffset, 0); } - public static void addIndicatorDotRGBs(FlatBufferBuilder builder, int indicatorDotRGBsOffset) { builder.addOffset(12, indicatorDotRGBsOffset, 0); } - public static void addIndicatorLineIDs(FlatBufferBuilder builder, int indicatorLineIDsOffset) { builder.addOffset(13, indicatorLineIDsOffset, 0); } - public static int createIndicatorLineIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startIndicatorLineIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorLineStartLocs(FlatBufferBuilder builder, int indicatorLineStartLocsOffset) { builder.addOffset(14, indicatorLineStartLocsOffset, 0); } - public static void addIndicatorLineEndLocs(FlatBufferBuilder builder, int indicatorLineEndLocsOffset) { builder.addOffset(15, indicatorLineEndLocsOffset, 0); } - public static void addIndicatorLineRGBs(FlatBufferBuilder builder, int indicatorLineRGBsOffset) { builder.addOffset(16, indicatorLineRGBsOffset, 0); } - public static void addLogs(FlatBufferBuilder builder, int logsOffset) { builder.addOffset(17, logsOffset, 0); } - public static void addRoundID(FlatBufferBuilder builder, int roundID) { builder.addInt(18, roundID, 0); } - public static void addBytecodeIDs(FlatBufferBuilder builder, int bytecodeIDsOffset) { builder.addOffset(19, bytecodeIDsOffset, 0); } - public static int createBytecodeIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startBytecodeIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addBytecodesUsed(FlatBufferBuilder builder, int bytecodesUsedOffset) { builder.addOffset(20, bytecodesUsedOffset, 0); } - public static int createBytecodesUsedVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startBytecodesUsedVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamNumBuffs(FlatBufferBuilder builder, int teamNumBuffsOffset) { builder.addOffset(21, teamNumBuffsOffset, 0); } - public static int createTeamNumBuffsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamNumBuffsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endRound(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java b/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java deleted file mode 100644 index b82bff1b..00000000 --- a/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java +++ /dev/null @@ -1,94 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * A list of new bodies to be placed on the map. - */ -public final class SpawnedBodyTable extends Table { - public static SpawnedBodyTable getRootAsSpawnedBodyTable(ByteBuffer _bb) { return getRootAsSpawnedBodyTable(_bb, new SpawnedBodyTable()); } - public static SpawnedBodyTable getRootAsSpawnedBodyTable(ByteBuffer _bb, SpawnedBodyTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public SpawnedBodyTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The numeric ID of the new bodies. - * Will never be negative. - * There will only be one body with a particular ID at a time. - * So, there will never be two robots with the same ID, or a robot and - * a building with the same ID. - */ - public int robotIDs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int robotIDsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer robotIDsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } - public ByteBuffer robotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } - /** - * The teams of the new bodies. - */ - public byte teamIDs(int j) { int o = __offset(6); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } - public int teamIDsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamIDsAsByteBuffer() { return __vector_as_bytebuffer(6, 1); } - public ByteBuffer teamIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 1); } - /** - * The types of the new bodies. - */ - public byte types(int j) { int o = __offset(8); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } - public int typesLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer typesAsByteBuffer() { return __vector_as_bytebuffer(8, 1); } - public ByteBuffer typesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 1); } - /** - * The locations of the bodies. - */ - public VecTable locs() { return locs(new VecTable()); } - public VecTable locs(VecTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * the amount of influence paid to create these bodies - * for initial Enlightenment Centers, this is the amount of influence - * needed to take over - */ - public int influences(int j) { int o = __offset(12); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int influencesLength() { int o = __offset(12); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer influencesAsByteBuffer() { return __vector_as_bytebuffer(12, 4); } - public ByteBuffer influencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 12, 4); } - - public static int createSpawnedBodyTable(FlatBufferBuilder builder, - int robotIDsOffset, - int teamIDsOffset, - int typesOffset, - int locsOffset, - int influencesOffset) { - builder.startObject(5); - SpawnedBodyTable.addInfluences(builder, influencesOffset); - SpawnedBodyTable.addLocs(builder, locsOffset); - SpawnedBodyTable.addTypes(builder, typesOffset); - SpawnedBodyTable.addTeamIDs(builder, teamIDsOffset); - SpawnedBodyTable.addRobotIDs(builder, robotIDsOffset); - return SpawnedBodyTable.endSpawnedBodyTable(builder); - } - - public static void startSpawnedBodyTable(FlatBufferBuilder builder) { builder.startObject(5); } - public static void addRobotIDs(FlatBufferBuilder builder, int robotIDsOffset) { builder.addOffset(0, robotIDsOffset, 0); } - public static int createRobotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startRobotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamIDs(FlatBufferBuilder builder, int teamIDsOffset) { builder.addOffset(1, teamIDsOffset, 0); } - public static int createTeamIDsVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } - public static void startTeamIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } - public static void addTypes(FlatBufferBuilder builder, int typesOffset) { builder.addOffset(2, typesOffset, 0); } - public static int createTypesVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } - public static void startTypesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } - public static void addLocs(FlatBufferBuilder builder, int locsOffset) { builder.addOffset(3, locsOffset, 0); } - public static void addInfluences(FlatBufferBuilder builder, int influencesOffset) { builder.addOffset(4, influencesOffset, 0); } - public static int createInfluencesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startInfluencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endSpawnedBodyTable(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/TeamData.java b/engine/src/main/battlecode/schema-old/TeamData.java deleted file mode 100644 index 32b840b1..00000000 --- a/engine/src/main/battlecode/schema-old/TeamData.java +++ /dev/null @@ -1,57 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * Data relevant to a particular team. - */ -public final class TeamData extends Table { - public static TeamData getRootAsTeamData(ByteBuffer _bb) { return getRootAsTeamData(_bb, new TeamData()); } - public static TeamData getRootAsTeamData(ByteBuffer _bb, TeamData obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public TeamData __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - /** - * The name of the team. - */ - public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); } - public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); } - /** - * The java package the team uses. - */ - public String packageName() { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer packageNameAsByteBuffer() { return __vector_as_bytebuffer(6, 1); } - public ByteBuffer packageNameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 1); } - /** - * The ID of the team this data pertains to. - */ - public byte teamID() { int o = __offset(8); return o != 0 ? bb.get(o + bb_pos) : 0; } - - public static int createTeamData(FlatBufferBuilder builder, - int nameOffset, - int packageNameOffset, - byte teamID) { - builder.startObject(3); - TeamData.addPackageName(builder, packageNameOffset); - TeamData.addName(builder, nameOffset); - TeamData.addTeamID(builder, teamID); - return TeamData.endTeamData(builder); - } - - public static void startTeamData(FlatBufferBuilder builder) { builder.startObject(3); } - public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } - public static void addPackageName(FlatBufferBuilder builder, int packageNameOffset) { builder.addOffset(1, packageNameOffset, 0); } - public static void addTeamID(FlatBufferBuilder builder, byte teamID) { builder.addByte(2, teamID, 0); } - public static int endTeamData(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - diff --git a/engine/src/main/battlecode/schema-old/Vec.java b/engine/src/main/battlecode/schema-old/Vec.java deleted file mode 100644 index 880323bb..00000000 --- a/engine/src/main/battlecode/schema-old/Vec.java +++ /dev/null @@ -1,29 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * A vector in two-dimensional space. Discrete space, of course. - * Defaults to the 0 vector. - */ -public final class Vec extends Struct { - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; } - public Vec __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - public int x() { return bb.getInt(bb_pos + 0); } - public int y() { return bb.getInt(bb_pos + 4); } - - public static int createVec(FlatBufferBuilder builder, int x, int y) { - builder.prep(4, 8); - builder.putInt(y); - builder.putInt(x); - return builder.offset(); - } -} - diff --git a/engine/src/main/battlecode/schema-old/VecTable.java b/engine/src/main/battlecode/schema-old/VecTable.java deleted file mode 100644 index 318ab618..00000000 --- a/engine/src/main/battlecode/schema-old/VecTable.java +++ /dev/null @@ -1,50 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -// package battlecode.schema; - -import java.nio.*; -import java.lang.*; -import java.util.*; -import com.google.flatbuffers.*; - -@SuppressWarnings("unused") -/** - * A table of vectors. - */ -public final class VecTable extends Table { - public static VecTable getRootAsVecTable(ByteBuffer _bb) { return getRootAsVecTable(_bb, new VecTable()); } - public static VecTable getRootAsVecTable(ByteBuffer _bb, VecTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } - public VecTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - public int xs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int xsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer xsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } - public ByteBuffer xsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } - public int ys(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int ysLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer ysAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } - public ByteBuffer ysInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } - - public static int createVecTable(FlatBufferBuilder builder, - int xsOffset, - int ysOffset) { - builder.startObject(2); - VecTable.addYs(builder, ysOffset); - VecTable.addXs(builder, xsOffset); - return VecTable.endVecTable(builder); - } - - public static void startVecTable(FlatBufferBuilder builder) { builder.startObject(2); } - public static void addXs(FlatBufferBuilder builder, int xsOffset) { builder.addOffset(0, xsOffset, 0); } - public static int createXsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startXsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addYs(FlatBufferBuilder builder, int ysOffset) { builder.addOffset(1, ysOffset, 0); } - public static int createYsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startYsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static int endVecTable(FlatBufferBuilder builder) { - int o = builder.endObject(); - return o; - } -} - From 961ad63413bbe28d4079485420751e3a8c3796e8 Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Wed, 21 Dec 2022 14:27:30 +1100 Subject: [PATCH 05/12] Remove more legacy --- build.gradle | 124 +----------------------------------------------- settings.gradle | 3 -- 2 files changed, 1 insertion(+), 126 deletions(-) diff --git a/build.gradle b/build.gradle index 78c8416b..02f53f01 100644 --- a/build.gradle +++ b/build.gradle @@ -9,22 +9,6 @@ sourceCompatibility = 1.8 // Fun fact: this line of code single-handedly fixed an error I spent two hours debugging. evaluationDependsOnChildren() -if (!project.hasProperty("teamA")) { - ext.teamA = "examplefuncsplayer" -} -if (!project.hasProperty("teamB")) { - ext.teamB = "examplefuncsplayer" -} -if (!project.hasProperty("maps")) { - ext.maps = "maptest" -} - -if (project.hasProperty("release_version")) { - if (!project.property("release_version").startsWith("2022")) { - throw new StopExecutionException("release version must start with 2022!") - } -} - configurations { scala @@ -100,69 +84,6 @@ task debug(type: JavaExec, dependsOn: [':engine:build', ':example-bots:build']) ] } -task headlessX(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots:build']) { - mainClass = 'battlecode.server.Main' - classpath = files(serverJar) + project(':internal-test-bots').sourceSets.main.output + configurations.scala - args = ['-c=-'] - jvmArgs = [ - '-Dbc.server.mode=headless', - '-Dbc.server.map-path=maps', - '-Dbc.server.debug=true', - '-Dbc.engine.debug-methods=true', - '-Dbc.engine.enable-profiler='+project.property('profilerEnabled'), - '-Dbc.game.team-a='+project.property('teamA'), - '-Dbc.game.team-b='+project.property('teamB'), - '-Dbc.game.team-a.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), - '-Dbc.game.team-b.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), - '-Dbc.game.maps='+project.property('maps'), - '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc22' - ] -} - -task debugX(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots:build']) { - mainClass = 'battlecode.server.Main' - classpath = files(serverJar) + project(':internal-test-bots').sourceSets.main.output + configurations.scala - args = ['-c=-'] - jvmArgs = [ - '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005', - '-Dbc.server.mode=headless', - '-Dbc.server.map-path=maps', - '-Dbc.server.debug=true', - '-Dbc.engine.debug-methods=true', - '-Dbc.engine.enable-profiler='+project.property('profilerEnabled'), - '-Dbc.game.team-a='+project.property('teamA'), - '-Dbc.game.team-b='+project.property('teamB'), - '-Dbc.game.team-a.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), - '-Dbc.game.team-b.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), - '-Dbc.game.maps='+project.property('maps'), - '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc22' - ] -} - - -task runFromClient(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots:build']) { - mainClass = 'battlecode.server.Main' - classpath = files(serverJar) + project(':internal-test-bots').sourceSets.main.output + configurations.scala - args = ['-c=-'] - jvmArgs = [ - '-Dbc.server.wait-for-client=true', - '-Dbc.server.mode=headless', - '-Dbc.server.map-path=maps', - '-Dbc.server.debug=false', - '-Dbc.server.robot-player-to-system-out=false', - '-Dbc.engine.debug-methods=true', - '-Dbc.engine.enable-profiler='+project.property('profilerEnabled'), - '-Dbc.game.team-a='+project.property('teamA'), - '-Dbc.game.team-b='+project.property('teamB'), - '-Dbc.game.team-a.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), - '-Dbc.game.team-b.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), - '-Dbc.game.maps='+project.property('maps'), - '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc22' - ] -} - - - task run(dependsOn: ['headless']) {} @@ -221,32 +142,6 @@ task release_docs(type: Jar, dependsOn: [':engine:javadoc']) { from new File(project(":engine").docsDir, "javadoc") } -task release_docs_zip(type: Zip, dependsOn: [':engine:javadoc']) { - doFirst { - if (!project.hasProperty("release_version") || project.property("release_version") == "unspecified") - throw new InvalidUserDataException("Must provide property \"release_version\"") - } - - archiveBaseName = "battlecode-javadoc" - if (project.hasProperty("release_version")) - version = project.property("release_version"); - destinationDirectory = project.projectDir; - - from new File(project(":engine").docsDir, "javadoc") -} - -task release_sources(type: Jar, dependsOn: classes) { - classifier = 'sources' - from project(":engine").sourceSets.main.allSource - - archiveBaseName = "battlecode-source" - if (project.hasProperty("release_version")) - version = project.property("release_version"); - destinationDirectory = project.projectDir; - - // from new File(project(":engine").sourceDir, "source") -} - task prodClient { doLast { exec { @@ -281,21 +176,7 @@ task releaseClientLinux32(type: Zip, dependsOn: ['prodClient']) { } - publishing { - repositories { - maven { - url = "https://us-east1-maven.pkg.dev/battlecode18/battlecode22-engine" - credentials { - username = "_json_key_base64" - password = System.getenv("ARTIFACT_REGISTRY_MAVEN_SECRET") - } - authentication { - basic(BasicAuthentication) - } - } - } - publications { server(MavenPublication) { groupId 'org.battlecode' @@ -307,9 +188,6 @@ publishing { artifact release_docs { classifier 'javadoc' } - artifact release_sources { - classifier 'sources' - } } clientWin(MavenPublication) { @@ -319,7 +197,7 @@ publishing { artifact releaseClientWin } - + clientMac(MavenPublication) { groupId 'org.battlecode' artifactId 'battlecode22-client-mac' diff --git a/settings.gradle b/settings.gradle index bc2e5443..2ca0853e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,2 @@ rootProject.name = 'battlecode-release' - include 'engine', 'example-bots' -include ":internal-test-bots" -project(":internal-test-bots").projectDir = file("battlecode20-internal-test-bots") From 95e9587e5f581fce2a21c6e82d5751a679ed67b6 Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Wed, 21 Dec 2022 15:58:53 +1100 Subject: [PATCH 06/12] Add automatic release --- .github/workflows/release.yml | 92 +++++++++++++++++++++++++++++++++++ gradle.properties | 1 - 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..7d338111 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,92 @@ +name: Release +on: + push: + tags: + - '*' + +env: + # GCS_BUCKET is the name of the Google Cloud Storage bucket to which all artifacts are deployed. + GCS_BUCKET: mitbattlecode-releases + + # RELEASE_ARTIFACT_ID is the name of the Maven artifact produced by the buildsystem. + # Important: you must make sure no ID is a prefix of a different ID. Otherwise, you could + # inadvertently cause unintended episodes to become public. + RELEASE_ARTIFACT_ID: battlecode22 + + # IS_PUBLIC is whether to release deployments publicly. Set to exactly the text "YES" to do so. + IS_PUBLIC: NO + +jobs: + release: + name: Release + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - name: Checkout branch + uses: actions/checkout@v3 + + - name: Get release version + run: | + release_version=${GITHUB_REF#refs/*/} + echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV + echo "The release version is $release_version" + + - name: Authenticate to Google Cloud Platform + uses: google-github-actions/auth@v1 + with: + create_credentials_file: true + workload_identity_provider: projects/830784087321/locations/global/workloadIdentityPools/releases/providers/github-workflow + service_account: releases-agent@mitbattlecode.iam.gserviceaccount.com + + - name: Set up Google Cloud SDK + uses: 'google-github-actions/setup-gcloud@v1' + + - name: Set up Wine # See actions/runner-images#743 + run: | + sudo dpkg --add-architecture i386 + wget -qO - https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - + sudo add-apt-repository ppa:cybermax-dexter/sdl2-backport + sudo apt-add-repository "deb https://dl.winehq.org/wine-builds/ubuntu $(lsb_release -cs) main" + sudo apt install --install-recommends winehq-stable + + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: 8 + distribution: adopt + + - name: Set up Node 16 + uses: actions/setup-node@v3 + with: + node-version: 16 + + - name: Install schema + run: npm install + working-directory: ./schema + + - name: Install client + run: npm run install-all + working-directory: ./client + + - name: Publish to local repository + run: ./gradlew publishToMavenLocal -Prelease_version=$RELEASE_VERSION + + - name: Determine access control + run: | + [[ "$IS_PUBLIC" = "YES" ]] && acl="public-read" || acl="project-private" + echo "OBJECT_ACL=$acl" >> $GITHUB_ENV + echo "Objects will be uploaded with ACL $acl" + + - name: Upload maven artifacts to remote repository + run: gsutil -m rsync -a $OBJECT_ACL -r $HOME/.m2/repository/org/battlecode gs://$GCS_BUCKET/maven/org/battlecode + + - name: Upload javadocs + run: | + unzip -d ${{ runner.temp }}/javadoc $HOME/.m2/repository/org/battlecode/$RELEASE_ARTIFACT_ID/$RELEASE_VERSION/*-javadoc.jar + gsutil -m rsync -a $OBJECT_ACL -r ${{ runner.temp }}/javadoc gs://$GCS_BUCKET/javadoc/$RELEASE_ARTIFACT_ID/$RELEASE_VERSION + + - name: Upload specs + run: gsutil -m rsync -a $OBJECT_ACL -r ./specs gs://$GCS_BUCKET/specs/$RELEASE_ARTIFACT_ID/$RELEASE_VERSION diff --git a/gradle.properties b/gradle.properties index f589204e..4dc98a43 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,3 @@ maps=maptestsmall profilerEnabled=false source=src mapLocation=maps -release_version=2022.2.2.0 From 7f95e825cc0ae9a100efcb874b78422d01d00bdb Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Wed, 21 Dec 2022 19:05:38 +1100 Subject: [PATCH 07/12] Update deploy documentation --- RELEASE_JAVA.md | 50 ++++++++-------------------------------- deploy/deploy-javadoc.sh | 33 -------------------------- deploy/deploy-specs.sh | 28 ---------------------- 3 files changed, 9 insertions(+), 102 deletions(-) delete mode 100644 deploy/deploy-javadoc.sh delete mode 100644 deploy/deploy-specs.sh diff --git a/RELEASE_JAVA.md b/RELEASE_JAVA.md index 6bc5ac01..59a55dd3 100644 --- a/RELEASE_JAVA.md +++ b/RELEASE_JAVA.md @@ -1,43 +1,11 @@ # HOW TO RELEASE A JAVA GAME -## Prereqs - -a bash-like shell (windows command prompt won't work for this). - -npm - -a git key: Obtain a git key that has "publish packages" permissions. This key is a string. Keep it around somewhere - -## Get updates - -Make sure you have all the most recent updates to the repo! (Ideally they're pushed to git. Then do git checkout master, git fetch, git pull.) - -## Update some version numbers - -`client/visualizer/src/config` -- find ``gameVersion`, and update that. - -`gradle.properties` -- update `release_version`. - -Make sure these updates are pushed to master! - -## Update specs and javadoc - -In our game spec (specs folder), make sure changes are up to date. - -Pay attention to the version number at the top of specs.md.html, and to the changelog at the bottom. - -push to master btw! - -## Release packages - -Set BC21_GITUSERNAME: `export BC21_GITUSERNAME=n8kim1`, etc - -Set BC21_GITKEY similarly. This git key is the string discussed above. - -./gradlew publish - -Now set version.txt in gcloud (also set cache policy to no-store) - -## Deploy frontend - -Run the deploy.sh script! For arguments, follow the instructions in the file. For example: `bash ./deploy.sh deploy 2021.3.0.2` +1. Update version numbers in the following places: + - `engine/src/main/battlecode/common/GameConstants.java` + - `client/visualizer/src/config.ts` + - Specs, both at the top and in the changelog. +2. Decide whether you want the release to be public. + - Check the value of `IS_PUBLIC` in `.github/workflows/release.yml`. +3. Create a Release on GitHub. + - The release tag-name will be the version number. For example: "1.0.3". + - You should use the version number as the release title too. diff --git a/deploy/deploy-javadoc.sh b/deploy/deploy-javadoc.sh deleted file mode 100644 index f8cbf67c..00000000 --- a/deploy/deploy-javadoc.sh +++ /dev/null @@ -1,33 +0,0 @@ -# TODO enforce state of repo up-to-date -# TODO enforce `gradle.properties` -- update `release_version`. -# TODO enforce that this update is pushed to master -# TODO note that java is a prereq. - -BUCKET_NAME="bc-game-storage" - -# TODO finish this, once i can actually get javadocs to work. -# Here's scraps of untested code: - -# cd .. -# # Assumes version as second arg to deploy script -# ./gradlew release_docs_zip -Prelease_version=$1 --stacktrace -# mv battlecode-javadoc-$1.zip javadoc.zip -# unzip -d javadoc javadoc.zip -# rm javadoc.zip -# mkdir frontend/public/javadoc -# mv javadoc frontend/public -# cd deploy - -# TODO put this into a bucket, and configure properly, etc - -read -p "IMPORTANT: Ensure that the docs are in the 'javadoc' folder. Press enter to proceed..." - -gsutil -m rm gs://$BUCKET_NAME/javadocs/2022/** -# Upload -cd ../javadoc -gsutil -m cp -r ** gs://$BUCKET_NAME/javadocs/2022/ -cd ../deploy -# Enforce cache policy -gsutil -m setmeta -h "Cache-Control:no-cache" -r gs://$BUCKET_NAME/javadocs/2022/** -# TODO public check -gsutil -m acl ch -u AllUsers:R -r gs://$BUCKET_NAME/javadocs/2022/** diff --git a/deploy/deploy-specs.sh b/deploy/deploy-specs.sh deleted file mode 100644 index 841d1d41..00000000 --- a/deploy/deploy-specs.sh +++ /dev/null @@ -1,28 +0,0 @@ -# TODO enforce state of repo up-to-date -# TODO enforce the following -- -# Pay attention to the version number at the top of specs.md.html, and to the changelog at the bottom. -# push to master! - -# Note: this script is not in the specs folder, on purpose -- -# I don't want this script to get deployed too. - -BUCKET_NAME="bc-game-storage" - -echo 'Do you wish to deploy these specs to the public? Type public and press enter.' -echo 'IMPORTANT: NEVER DO THIS BEFORE THE GAME IS RELEASED' -read -p 'input: ' ispublic - -# Handle bucket: -# Clean -gsutil -m rm gs://$BUCKET_NAME/specs/2022/** -# Upload -cd ../specs -gsutil -m cp -r ** gs://$BUCKET_NAME/specs/2022/ -cd ../deploy -# Enforce cache policy -gsutil -m setmeta -h "Cache-Control:no-cache" -r gs://$BUCKET_NAME/specs/2022/** -# Make public? -if [ "$ispublic" == 'public' ] -then - gsutil -m acl ch -u AllUsers:R -r gs://$BUCKET_NAME/specs/2022/** -fi From 24c815465f12197c21b19aef4cc8ffbed03af33c Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Wed, 21 Dec 2022 21:14:48 +1100 Subject: [PATCH 08/12] Deploy web client on CI --- .github/workflows/release.yml | 10 +++++++ client/deploy-web-client.sh | 47 ------------------------------- client/visualizer/visualizer.html | 2 +- 3 files changed, 11 insertions(+), 48 deletions(-) delete mode 100644 client/deploy-web-client.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d338111..c7888071 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -74,6 +74,10 @@ jobs: - name: Publish to local repository run: ./gradlew publishToMavenLocal -Prelease_version=$RELEASE_VERSION + - name: Build web client + run: npm run prod + working-directory: ./client/visualizer + - name: Determine access control run: | [[ "$IS_PUBLIC" = "YES" ]] && acl="public-read" || acl="project-private" @@ -90,3 +94,9 @@ jobs: - name: Upload specs run: gsutil -m rsync -a $OBJECT_ACL -r ./specs gs://$GCS_BUCKET/specs/$RELEASE_ARTIFACT_ID/$RELEASE_VERSION + + - name: Upload web client + run: | + gsutil -m rsync -a $OBJECT_ACL out gs://$GCS_BUCKET/client/$RELEASE_ARTIFACT_ID/$RELEASE_VERSION + gsutil cp -a $OBJECT_ACL visualizer.html gs://$GCS_BUCKET/client/$RELEASE_ARTIFACT_ID/$RELEASE_VERSION + working-directory: ./client/visualizer diff --git a/client/deploy-web-client.sh b/client/deploy-web-client.sh deleted file mode 100644 index 66a50b11..00000000 --- a/client/deploy-web-client.sh +++ /dev/null @@ -1,47 +0,0 @@ -# TODO move this to deploy folder -# TODO enforce state of repo up-to-date -# TODO year as arg -# TODO prereqs: npm, tsc, java?, flatc - -BUCKET_NAME="bc-game-storage" -# TODO make gs://$BUCKET_NAME/clients/2022/ a var, and use it - -echo "IMPORTANT: Make sure that gameVersion is updated in client/visualizer/src/config." -echo "If it is not, change it now. Make sure to push to the repo later too." -read -p "Press enter to proceed..." - -cd ../schema -npm install -# Don't do npm run build; -# this regenerates flatbuffers which is pretty annoying -# npm run build -# TODO the following replacement could be done automatically i think -# echo "IMPORTANT: " -# echo "NOW, change line 3 of schema/ts/battlecode_generated.ts to \`import { flatbuffers } from \"flatbuffers\"\`." -# echo "DON'T FORGET TO SAVE!" -# read -p "When done, press enter to proceed..." -cd ../client - -cd playback -npm install -npm run build -cd ../visualizer -npm install -npm run prod -cd .. - -read -p "Press Ctrl-C if things don't look right. If done, press enter to proceed..." - -gsutil -m rm gs://$BUCKET_NAME/clients/2022/** -gsutil -m cp -r visualizer/out gs://$BUCKET_NAME/clients/2022/ -gsutil -m cp visualizer/visualizer.html gs://$BUCKET_NAME/clients/2022/ -gsutil -m setmeta -h "Cache-Control:no-cache" -r gs://$BUCKET_NAME/clients/2022/** - -echo 'Do you wish to deploy the client to the public? Type public and press enter.' -echo 'IMPORTANT: NEVER DO THIS BEFORE THE GAME IS RELEASED' -read -p 'input: ' ispublic -if [ "$ispublic" == 'public' ] -then - gsutil -m acl ch -u AllUsers:R -r gs://$BUCKET_NAME/clients/2022/** -fi - diff --git a/client/visualizer/visualizer.html b/client/visualizer/visualizer.html index 83aabde6..993a8cc2 100644 --- a/client/visualizer/visualizer.html +++ b/client/visualizer/visualizer.html @@ -15,7 +15,7 @@