battlecode / battlecode19 Goto Github PK
View Code? Open in Web Editor NEWReact & Django
License: GNU General Public License v3.0
React & Django
License: GNU General Public License v3.0
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.
Saves us money, saves them privacy if they're deving something new. I guess also needs to be reflected in segs stuff.
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:
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.
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.
So we can get files through a link like https://www.battlecode.org/img/avatar/1.png rather than an s3 link. Also authenticate before serving files like logs or submissions.
Should be a simple change to the settings. SQLite is just easier for testing...
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.
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.
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.
For ease and style correctness on app.
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:
Back end:
When there's a foreign key, many to many field, or one to one field, it may help to return a nested serialization, which is more meaningful than an ID slug.
Currently don't bundle and minify everything, and have unnecessary/redundant dependencies, leading to long load times.
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:
code
field from team table, and properly handle submissionsAfter 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...
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.
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.
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.
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.
to get trueskill, get most recent ranked scrimmage for that team and pull from there
this allows us to have timeseries data which is useful
Create some sort of benchmark that facilitates automatic adjustment of chess clock timing for different platforms to make development easier.
Need to be able to get a list of timeline event JSON, eg [{'name':'season start','time':...},...]
. Just need season start and end and tournaments.
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.
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.
Here's what I did:
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
.
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.
Auto-generated docs are somewhat misleading with regards to which fields are actually required and what they mean.
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.
Pick a random color, color in the battlecode logo in with it
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.
Special user role to update scrimmage information like logs, replay files, etc. through an endpoint. Regular users should not be allowed to do this.
Set up auto-scrimmaging, so scrimmages can be run every 15 minutes and automatically face teams against each other.
Front-end:
Back-end:
Infrastructure:
Both localhost:8000/api/user
and localhost:8000/api/user/
should work.
We probably don't need half these dependencies.
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
This is implemented in the API, but currently in the front-end we always only show the first page of results.
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.
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}
I think it's built into Django but not sure.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.