Git Product home page Git Product logo

battlecode19's People

Contributors

arvid220u avatar awesomelemonade avatar benjaminfspector avatar j-mao avatar joshuagruenstein avatar jsegaran avatar kelvin-lu avatar moreheadm avatar npfoss avatar nthistle avatar stefangimmillaro avatar stephanie-fu avatar thevaffel avatar ygina avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

battlecode19's Issues

Optimize database performance

Indexes and google other SQL performance tips.

For example, it's probably slow to match users to teams because there are no foreign keys in array fields, which means no automatic indexing. Although it's fast to query all the submissions of a team of a certain tournament (due to indexing on foreign keys), it might be slow to get the most recent submission if there are a lot of submissions.

Scrimmage Endpoint

SCRIMMAGE = {league, red_team, blue_team, map, ranked, red_submission, blue_submission, status, replay, red_logs, blue_logs, requested_by, requested_at, started_at, updated_at}

  • POST /<league>/scrimmage
    In: {red_team, blue_team, map, ranked}
    Out: SCRIMMAGE
    Creates a scrimmage in the league, where the authenticated user is on one of the participating teams. The map and each team must also be in the league. If the requested team auto accepts this scrimmage, then the scrimmage is automatically queued with each team's most recent submission.

  • GET /<league>/scrimmage
    In: {tournament, statuses}
    Out: [SCRIMMAGE]
    Retrieves a list of scrimmages in the league, where the authenticated user is on one of the participating teams. The scrimmages are returned in descending order of requested at time. Optionally filters the scrimmages to only include those with the requested statuses (pending, queued, running, redwon, bluewon, rejected, failed, cancelled), or from the requested tournament. If the tournament parameter is not given, only lists non-tournament scrimmages.

  • GET /<league>/scrimmage/<scrimmageid>
    In: None
    Out: SCRIMMAGE
    Retrieves a scrimmage in the league, where the authenticated user is on one of the participating teams.

  • PATCH /<league>/scrimmage/<scrimmageid>/accept/

  • PATCH /<league>/scrimmage/<scrimmageid>/reject/

  • PATCH /<league>/scrimmage/<scrimmageid>/cancel/
    In: {}
    Out: SCRIMMAGE
    Updates the scrimmage in the league, where the authenticated user is on one of the participating teams. Includes the following operations:

  • "accept": Accepts an incoming scrimmage, queuing the game with each team's most recent submissions.
  • "reject": Rejects an incoming scrimmage.
  • "cancel": Cancels an outgoing scrimmage.

Castle talks do not work after Action object is created

This issue exists in Java and possibly also other languages.

Any castle talks (and quite likely also radio broadcasts) sent after the Action object is created are lost and never enacted. In code like the following, the new unit is built but the castle talk is not received.

Action tmp = buildUnit(SPECS.PILGRIM,1,0);
castleTalk(42);
return tmp;

This is because all castle talks are incorporated as fields within Action objects. Changes to the value of castle_talk are not reflected in the Action object and are therefore lost when that Action object is returned.

Submission Endpoint

  • POST /<league>/submission
    In: {red_team, blue_team, map, ranked}
    Out: SUBMISSION
    Uploads a submission for the authenticated user's team in this league.

  • GET /<league>/submission
    In: None
    Out: [SUBMISSION]
    Retrieves a list of submissions in descending order of submission time. Each submission belongs to the authenticated user's team in this league.

  • GET /<league>/submission/<submissionid>
    In: None
    Out: SUBMISSION
    Retrieves a submission, where the submission belongs to the authenticated user's team in this league.

Nondeterminism in games due to Math.random

Nondeterminism is introduced by the use of Math.random in game.js to shuffle the array returned by getVisibleRobots(); as a result, multiple executions of the same bots on a map with the same seed may yield a different result, even if the bots themselves use deterministic RNGs.

IFrame Startup Time Counts Against WallClock AND Fix Security Bug

Thank you devs for setting up Battlecode. I was observing how the code runs, and unfortunately, it appears as though initial startup code evaluation time counts against the allotted execution time for the bot. One possible fix is changing eval to Function and passing three parameters like so. This will allow the time the code starts to be recorded inside the code itself. Then, Object.freeze will prevent tampering with this number.

The security bug is that the robot can use window.parent and window.top to access the global namespace and communicate with other robots instantly and sabotage the other team. The solution is to delete window.parent and delete window.top to prevent access

function runCode(codeString, wallClockReference){
    // wallClockReference is an array whose first index will be set to the time now
    var iframeElement = document.createElement("iframe");
    iframeElement.width = iframeElement.height = "0";
    iframeElement.setAttribute("style", "border-width:0px");
    document.body.appendChild(iframeElement);
    codeString = '"use strict";arguments[0][0]=arguments[1].now();arguments[2](arguments[0]);' + codeString;
    var ctxWindow = iframeElement.contentWindow;
	var timeObj = [];
    // patch security bugs: //
    delete ctxWindow.parent;
    delete ctxWindow.top;
    ///////////////////////////
    var resultingValue = ctxWindow.Function(codeString).call(
        ctxWindow, // `this`
        timeObj, // arguments[0]
        performance, // arguments[1]
        Object.freeze // arguments[2]
    );
	wallClockReference.push(timeObj[0], performance.now()); // use Array.prototype.push to reduce delay
    document.body.removeChild(iframeElement);
    return resultingValue;
}

Observe the difference using the test code below.

(function(){
    var startTime = performance.now();
    var val = [];
    runCode('for(var i=0;i<128;i++);'.repeat(4096) + 'console.log("Hello World")', val);
	var endTime = performance.now();
	console.log("Timing the way it is now:    " + (endTime - startTime));
	console.log("Timing the way it should be: " + (val[1] - val[0]));
     ;
	
})();

As seen, without this optimization, the user's granted execution time can in some times be halved. I do not know about you, but I for one do not believe that code parsing time should count against you. Rather, only code startup time and execution time should count against you.

Token-based authentication

A client should be able to provide the necessary credentials and obtain a token from the website. If the token is included with future requests, the client will be authenticated to perform those requests. This feature is probably included in some built-in Django auth view, but it's important to confirm (and document) so we can use this with other Battlecode applications.

Check out documentation for JWT Rest Framework authentication. The website currently uses simple JWT auth but it's black magic to me.

Sponsor Portal

Create a sponsor port, so sponsors can look through and filter participants by rank, grade, and location, and then export a list of resumes.

Front end:

  • Create a portal for sponsors to log in.
  • Create a search functionality for
    • Rank
    • Grade
    • Location
    • Competition (e.g. Battlehack, Battlecode, ...)
  • Allow exporting of resumes either through email, google cloud, or direct download.

Back end:

  • Create log in endpoint for sponsors
  • Create search ability for users
  • Allow zipping and export of resumes. Could upload to gc.

Team Endpoint

TEAM = {name, avatar, users, bio, divisions, auto_accept_ranked, auto_accept_unranked}

  • POST /<league>/team
    In: {name}
    Out: TEAM
    Creates a team in this league. The authenticated user automatically joins the team.

  • GET /<league>/team
    In: None
    Out: [TEAM]
    Lists active teams in the league, ordered by team name.

  • GET /<league>/team/<teamid>
    In: None
    Out: TEAM + (team_key)
    Retrieves an active team in the league. Also gets the team key if the authenticated user is on this team.

  • PATCH /<league>/team/<teamid>
    In: {op, (bio, divisions, auto_accept_ranked, auto_accept_unranked, team_key)}
    Out: TEAM
    Updates the team. The authenticated user must be on this team. Includes the following operations:

  • "join" - Joins the team. Fails if the team has the maximum number of members, or if the team key is incorrect.
  • "leave" - Leaves the team. Deletes the team if this is the last user to leave the team.
  • "update" - Updates the team bio, divisions, or auto-accepting for ranked and unranked scrimmages.

Undo Battlehack hackiness with API

  • Remove code field from team table, and properly handle submissions
  • Properly serve replays through static storage
  • Properly handle avatars
  • Standardize API endpoints

Page not found at /

After following the read me and installing everything in the requirements.txt. I proceeded to run the server and when I open a web browser and go to http://127.0.0.1:8000/ I get a 404 error in my browser that looks like:

Request Method: | GET
-- | --
http://127.0.0.1:8000/
Using the URLconf defined in urls, Django tried these URL patterns, in this order:
__debug__/
auth/token/
auth/token/refresh/
auth/token/verify/
api/
admin/
docs/
api/password_reset/
The empty path didn't match any of these.

and in my terminal I get:

Not Found: /
[05/Feb/2019 00:24:55] "GET / HTTP/1.1" 404 2700

Any help would be appreciated, Im really stuck...

ID vs other primary key in URL

URLs currently take IDs as parameters for things like league, tournament, team, user, etc. It might be more user-friendly to use their unique names instead of IDs as a parameter.

Multipart file upload

To upload larges files like team and user avatars, player code, etc. Start with user avatars for now and it should be easily portable when remaining functionality is implemented.

Custom permission classes

Authorization for endpoints should generally be done through Django permission classes, not manually inside the view logic. Creating permission classes would reduce repetitive code for things like, checking that an authenticated user can only perform write operations on itself, only members of a team can modify that team, only participants in a tournament can blah blah blah.

Dev alerts

Allow us as devs to broadcast alerts to users. Should only be accessible by logged in users with auth. API should allow users to get all alerts.

Trouble changing name and date of birth on profile

Earlier today, I noticed I had set the wrong year for my date of birth on my Battlecode account. I tried to change it from the account page, but typing in the text field or trying to clear existing text did nothing. I noticed the same thing happening for the first and last name fields. I eventually fixed it using the JavaScript developer tools, but I don't think this hacky approach should be necessary.

Change and reset passwords

A password is required to change a password. A password should maybe be required to change other user info? Integrate email confirmations with password resets, and also with account creation.

  • Change passwords
  • Send email confirmation on password reset
  • Send email confirmation on account creation

Can't request scrimmages in a team with a name of a previously-deleted team

Here's what I did:

  1. Create a team named '∞'
  2. Leave my team
  3. Create another team named '∞'
  4. Request a scrimmage from someone

This is the error I get (it's an HTTP 400 response):

The "it returned 2" becomes "it returned 3" if I re-create my team with the same name, and 4 if I do it again.

Here's how I think it can be fixed (I have no Django experience so I got no idea how to code this):
When a team is deleted, team.deleted is set to True. When the ScrimmageSerializer is used to check whether the team names of the teams participating in the requested scrimmage are valid, it requests all Team objects and tries to match by name. Since there are now multiple teams with name "∞", this returns multiple results which is not allowed. I'm guessing this can be fixed by making sure the Team.objects.all() results are filtered to only include teams with deleted set to False.

Coldbrew sourcemap support

For better error reporting. The transpiler API currently does generate this for Python and Java, we just don't use it in CrossVM. Would also have to generate a sourcemap for JS, as our "compilation" stage screws with line numbers.

Resume portal

  • Competitor resume upload
  • API view to get resumes and player profiles for a league if user has special status
  • Frontend portal for competitor and resume viewing for sponsors

Tournament Endpoint

TOURNAMENTSCRIMMAGE = {round, subround, red_team, blue_team, status, replay}

  • GET /<league>/tournament
    In: None
    Out: [TOURNAMENT]
    Retrieves a list of tournaments in this league.

  • GET /<league>/tournament/<tournamentid>
    In: None
    Out: TOURNAMENT
    Retrieves a tournament in this league.

  • Get /<league>/tournament/<tournamentid>/bracket
    In: None
    Out: [[TOURNAMENTSCRIMMAGE],...]
    Retrieves the bracket for a tournament in this league. Formatted as a list of rounds, where each round is a list of subrounds. The status of a scrimmage is redacted if the winner is meant to be hidden.

Map Endpoint

  • GET /<league>/map
    In: None
    Out: [MAP]
    Retrieves a public list of maps in this league.

  • GET /<league>/map/<mapid>
    In: None
    Out: MAP
    Retrieves a public map in this league.

Comprehensive CLI for web-averse users

  • Login flow
  • Shortcuts for git repo cloning/initialization
  • Offline Coldbrew match running & compilation, with Electron pop-up visualizer
  • Scrimmage requesting, listing, and viewing
  • Install crossplatform with a single shell command, no other dependencies

Matchrunner user role

Special user role to update scrimmage information like logs, replay files, etc. through an endpoint. Regular users should not be allowed to do this.

Auto-Scrimmaging

Set up auto-scrimmaging, so scrimmages can be run every 15 minutes and automatically face teams against each other.

Front-end:

  • Button to chose whether or not to be a part of the auto-scrimmaging system

Back-end:

  • API endpoint to get all teams that have auto-scrimmaging on

Infrastructure:

  • Get a sub-system to add scrimmages to the queue every 15 minutes

Blue castle gets extra turn if there is only one castle and red takes no action

The code used to test this is as follows

    public Action turn() {

        if(!PLAY_AS_RED && me.team == SPECS.BLUE) return null; // Exit if red and not supposed to be red, used to reduce log spam when not testing team interaction

        if (me.unit == SPECS.CASTLE) {
            log("I AM A CASTLE ON TURN " + me.turn);
            if (me.turn == 1) {
                return buildUnit(SPECS.PILGRIM,1,0);
            }
        }

        if (me.unit == SPECS.PILGRIM) {
            log("I AM A PILGRIM ON TURN " + me.turn);
        }

        return null;
    }

PLAY_AS_RED is a constant defined earlier in the file, setting PLAY_AS_RED to true, or changing that line to return null if blue does not show the error, however if there is only one castle, the code above with PLAY_AS_RED false, will give output similar to:

[Robot 2177 Log] I AM A CASTLE ON TURN 1
[Robot 2177 Log] I AM A CASTLE ON TURN 2
[Robot 3704 Log] I AM A PILGRIM ON TURN 1

Pagination on frontend

This is implemented in the API, but currently in the front-end we always only show the first page of results.

  • Search page
  • Scrimmage page
  • Updates page

League Endpoint

LEAGUE = {name, code, start_data, end_date, active}

  • GET /league
    In: None
    Out: [LEAGUE]
    Retrieves a list of leagues.

  • GET /league/<leagueid>
    In: None
    Out: LEAGUE
    Retrieves a league.

User Endpoint

  • POST /user/confirm
    In: {registration_token}

  • POST /user/reset_password
    In: {email}

  • PATCH /user/reset_password
    In: {reset_token, new_password}

  • PATCH /user/{userid}/change_password
    Auth: current user only
    In: {old_password, new_password}

  • PATCH /user/{userid}/upload
    Auth: current user only
    In: {op (avatar/resume), bytes}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.