version 1 of API

This commit is contained in:
Malachy Byrne 2022-11-05 15:44:23 +00:00
parent 074fcad25c
commit c821079a89
Signed by: malmal200
GPG Key ID: EC21443030A655D9
7 changed files with 1167 additions and 38 deletions

View File

@ -16,19 +16,298 @@ const docTemplate = `{
"host": "{{.Host}}", "host": "{{.Host}}",
"basePath": "{{.BasePath}}", "basePath": "{{.BasePath}}",
"paths": { "paths": {
"/": { "/cure": {
"get": { "get": {
"description": "Home page", "description": "Cures a zombie or infected human",
"produces": [ "produces": [
"application/json" "text/plain"
],
"summary": "Cure",
"parameters": [
{
"type": "string",
"description": "Target ID",
"name": "target",
"in": "path",
"required": true
}
], ],
"summary": "Home",
"responses": { "responses": {
"200": { "200": {
"description": "OK" "description": "OK"
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
},
"403": {
"description": "No cures available",
"schema": {
"type": "string"
}
},
"404": {
"description": "Target does not exist",
"schema": {
"type": "string"
}
},
"409": {
"description": "Target is not a zombie",
"schema": {
"type": "string"
}
} }
} }
} }
},
"/kill": {
"get": {
"description": "Kills a zombie if user is authenticated as a human. Gives zombie target the stunned state",
"produces": [
"text/plain"
],
"summary": "Kill",
"parameters": [
{
"type": "string",
"description": "Target ID",
"name": "target",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
},
"403": {
"description": "Killer is not a human",
"schema": {
"type": "string"
}
},
"404": {
"description": "Target does not exist",
"schema": {
"type": "string"
}
},
"409": {
"description": "Target is not a zombie",
"schema": {
"type": "string"
}
}
}
}
},
"/login": {
"post": {
"description": "Login",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Login",
"parameters": [
{
"description": "Player login",
"name": "info",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/main.Login"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/main.Player"
}
},
"400": {
"description": "Bad Request"
},
"403": {
"description": "Forbidden"
}
}
}
},
"/me": {
"get": {
"description": "Shows user information",
"produces": [
"application/json"
],
"summary": "Me",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/main.Player"
}
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
}
}
}
},
"/revive": {
"get": {
"description": "Revives a stunned zombie",
"produces": [
"text/plain"
],
"summary": "Revive",
"parameters": [
{
"type": "string",
"description": "Target ID",
"name": "target",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
},
"403": {
"description": "No revives available",
"schema": {
"type": "string"
}
},
"404": {
"description": "Target does not exist",
"schema": {
"type": "string"
}
},
"409": {
"description": "Target is not stunned",
"schema": {
"type": "string"
}
}
}
}
},
"/tag": {
"get": {
"description": "Tag a human as a zombie. Gives target the infected state if user is a zombie or core zombie.",
"produces": [
"text/plain"
],
"summary": "Tag",
"parameters": [
{
"type": "string",
"description": "Target ID",
"name": "target",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
},
"403": {
"description": "Tagger is not a zombie",
"schema": {
"type": "string"
}
},
"404": {
"description": "Target does not exist",
"schema": {
"type": "string"
}
},
"409": {
"description": "Target is not human",
"schema": {
"type": "string"
}
}
}
}
}
},
"definitions": {
"main.Login": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"main.Player": {
"type": "object",
"properties": {
"cures": {
"type": "integer"
},
"extensions": {
"type": "integer"
},
"id": {
"type": "string"
},
"kills": {
"type": "integer"
},
"last_kill": {
"type": "string"
},
"last_tagged": {
"type": "string"
},
"name": {
"type": "string"
},
"revives": {
"type": "integer"
},
"state": {
"type": "integer"
}
}
} }
} }
}` }`

View File

@ -8,19 +8,298 @@
}, },
"basePath": "/", "basePath": "/",
"paths": { "paths": {
"/": { "/cure": {
"get": { "get": {
"description": "Home page", "description": "Cures a zombie or infected human",
"produces": [ "produces": [
"application/json" "text/plain"
],
"summary": "Cure",
"parameters": [
{
"type": "string",
"description": "Target ID",
"name": "target",
"in": "path",
"required": true
}
], ],
"summary": "Home",
"responses": { "responses": {
"200": { "200": {
"description": "OK" "description": "OK"
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
},
"403": {
"description": "No cures available",
"schema": {
"type": "string"
}
},
"404": {
"description": "Target does not exist",
"schema": {
"type": "string"
}
},
"409": {
"description": "Target is not a zombie",
"schema": {
"type": "string"
}
} }
} }
} }
},
"/kill": {
"get": {
"description": "Kills a zombie if user is authenticated as a human. Gives zombie target the stunned state",
"produces": [
"text/plain"
],
"summary": "Kill",
"parameters": [
{
"type": "string",
"description": "Target ID",
"name": "target",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
},
"403": {
"description": "Killer is not a human",
"schema": {
"type": "string"
}
},
"404": {
"description": "Target does not exist",
"schema": {
"type": "string"
}
},
"409": {
"description": "Target is not a zombie",
"schema": {
"type": "string"
}
}
}
}
},
"/login": {
"post": {
"description": "Login",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Login",
"parameters": [
{
"description": "Player login",
"name": "info",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/main.Login"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/main.Player"
}
},
"400": {
"description": "Bad Request"
},
"403": {
"description": "Forbidden"
}
}
}
},
"/me": {
"get": {
"description": "Shows user information",
"produces": [
"application/json"
],
"summary": "Me",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/main.Player"
}
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
}
}
}
},
"/revive": {
"get": {
"description": "Revives a stunned zombie",
"produces": [
"text/plain"
],
"summary": "Revive",
"parameters": [
{
"type": "string",
"description": "Target ID",
"name": "target",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
},
"403": {
"description": "No revives available",
"schema": {
"type": "string"
}
},
"404": {
"description": "Target does not exist",
"schema": {
"type": "string"
}
},
"409": {
"description": "Target is not stunned",
"schema": {
"type": "string"
}
}
}
}
},
"/tag": {
"get": {
"description": "Tag a human as a zombie. Gives target the infected state if user is a zombie or core zombie.",
"produces": [
"text/plain"
],
"summary": "Tag",
"parameters": [
{
"type": "string",
"description": "Target ID",
"name": "target",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "User is not logged in",
"schema": {
"type": "string"
}
},
"403": {
"description": "Tagger is not a zombie",
"schema": {
"type": "string"
}
},
"404": {
"description": "Target does not exist",
"schema": {
"type": "string"
}
},
"409": {
"description": "Target is not human",
"schema": {
"type": "string"
}
}
}
}
}
},
"definitions": {
"main.Login": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"main.Player": {
"type": "object",
"properties": {
"cures": {
"type": "integer"
},
"extensions": {
"type": "integer"
},
"id": {
"type": "string"
},
"kills": {
"type": "integer"
},
"last_kill": {
"type": "string"
},
"last_tagged": {
"type": "string"
},
"name": {
"type": "string"
},
"revives": {
"type": "integer"
},
"state": {
"type": "integer"
}
}
} }
} }
} }

View File

@ -1,4 +1,33 @@
basePath: / basePath: /
definitions:
main.Login:
properties:
name:
type: string
password:
type: string
type: object
main.Player:
properties:
cures:
type: integer
extensions:
type: integer
id:
type: string
kills:
type: integer
last_kill:
type: string
last_tagged:
type: string
name:
type: string
revives:
type: integer
state:
type: integer
type: object
info: info:
contact: {} contact: {}
description: This is the Swagger documentation for DCU Games Society's 2022 Humans description: This is the Swagger documentation for DCU Games Society's 2022 Humans
@ -6,13 +35,169 @@ info:
title: DCU Games Society Humans Vs Zombies title: DCU Games Society Humans Vs Zombies
version: "1.0" version: "1.0"
paths: paths:
/: /cure:
get: get:
description: Home page description: Cures a zombie or infected human
parameters:
- description: Target ID
in: path
name: target
required: true
type: string
produces:
- text/plain
responses:
"200":
description: OK
"401":
description: User is not logged in
schema:
type: string
"403":
description: No cures available
schema:
type: string
"404":
description: Target does not exist
schema:
type: string
"409":
description: Target is not a zombie
schema:
type: string
summary: Cure
/kill:
get:
description: Kills a zombie if user is authenticated as a human. Gives zombie
target the stunned state
parameters:
- description: Target ID
in: path
name: target
required: true
type: string
produces:
- text/plain
responses:
"200":
description: OK
"401":
description: User is not logged in
schema:
type: string
"403":
description: Killer is not a human
schema:
type: string
"404":
description: Target does not exist
schema:
type: string
"409":
description: Target is not a zombie
schema:
type: string
summary: Kill
/login:
post:
consumes:
- application/json
description: Login
parameters:
- description: Player login
in: body
name: info
required: true
schema:
$ref: '#/definitions/main.Login'
produces: produces:
- application/json - application/json
responses: responses:
"200": "200":
description: OK description: OK
summary: Home schema:
$ref: '#/definitions/main.Player'
"400":
description: Bad Request
"403":
description: Forbidden
summary: Login
/me:
get:
description: Shows user information
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/main.Player'
"401":
description: User is not logged in
schema:
type: string
summary: Me
/revive:
get:
description: Revives a stunned zombie
parameters:
- description: Target ID
in: path
name: target
required: true
type: string
produces:
- text/plain
responses:
"200":
description: OK
"401":
description: User is not logged in
schema:
type: string
"403":
description: No revives available
schema:
type: string
"404":
description: Target does not exist
schema:
type: string
"409":
description: Target is not stunned
schema:
type: string
summary: Revive
/tag:
get:
description: Tag a human as a zombie. Gives target the infected state if user
is a zombie or core zombie.
parameters:
- description: Target ID
in: path
name: target
required: true
type: string
produces:
- text/plain
responses:
"200":
description: OK
"401":
description: User is not logged in
schema:
type: string
"403":
description: Tagger is not a zombie
schema:
type: string
"404":
description: Target does not exist
schema:
type: string
"409":
description: Target is not human
schema:
type: string
summary: Tag
swagger: "2.0" swagger: "2.0"

5
go.mod
View File

@ -14,14 +14,19 @@ require (
github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect
github.com/go-openapi/spec v0.20.7 // indirect github.com/go-openapi/spec v0.20.7 // indirect
github.com/go-openapi/swag v0.22.3 // indirect github.com/go-openapi/swag v0.22.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/sessions v1.2.1 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-sqlite3 v1.14.16 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe // indirect github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe // indirect
github.com/swaggo/swag v1.8.7 // indirect github.com/swaggo/swag v1.8.7 // indirect
github.com/urfave/cli/v2 v2.23.0 // indirect github.com/urfave/cli/v2 v2.23.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/net v0.1.0 // indirect golang.org/x/net v0.1.0 // indirect
golang.org/x/sys v0.1.0 // indirect golang.org/x/sys v0.1.0 // indirect
golang.org/x/tools v0.2.0 // indirect golang.org/x/tools v0.2.0 // indirect

10
go.sum
View File

@ -24,8 +24,14 @@ github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyr
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@ -38,6 +44,8 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
@ -63,6 +71,8 @@ github.com/urfave/cli/v2 v2.23.0 h1:pkly7gKIeYv3olPAeNajNpLjeJrmTPYCoZWaV+2VfvE=
github.com/urfave/cli/v2 v2.23.0/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/cli/v2 v2.23.0/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=

361
main.go
View File

@ -1,17 +1,104 @@
package main package main
import ( import (
"database/sql"
"encoding/json" "encoding/json"
//"errors"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"time" "time"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/sessions"
"github.com/swaggo/http-swagger" "github.com/swaggo/http-swagger"
_ "github.com/mattn/go-sqlite3"
_ "games.dcu.ie/hvz/v2/docs" _ "games.dcu.ie/hvz/v2/docs"
) )
var store = sessions.NewCookieStore([]byte("wuhcwe789cui"))
var db *sql.DB
func get_all_players() []Player {
rows, _ := db.Query("SELECT id FROM players")
players := []Player{}
var t_player Player
var id string
for rows.Next() {
rows.Scan(&id)
t_player, _ = get_player(id)
players = append(players, t_player)
}
return players
}
func update() {
for {
players := get_all_players()
for _, player := range players {
if (player.State == InfectedHuman &&
time.Since(player.Last_tagged).Seconds() >= 30) {
player.State = Zombie
player.Last_kill = time.Now()
}
if (player.State == StunnedZombie &&
time.Since(player.Last_tagged).Seconds() >= 15) {
player.State = Zombie
player.Last_kill = time.Now()
}
if (player.State == StunnedCoreZombie &&
time.Since(player.Last_tagged).Seconds() >= 10) {
player.State = CoreZombie
player.Last_kill = time.Now()
}
if (player.State == Zombie &&
time.Since(player.Last_kill).Seconds() >= 24) {
if (player.Extensions == 0) {
player.State = Dead
} else {
player.Extensions -= 1
}
}
save_player(player)
time.Sleep(5 * time.Second)
}
}
}
func get_player(id string) (Player, error) {
tmp_player := Player{}
var last_tagged string
var last_kill string
time_format := time.RFC3339
row := db.QueryRow("SELECT * FROM players WHERE id = ?", id)
err := row.Scan(&tmp_player.Id, &tmp_player.Name, &tmp_player.password, &tmp_player.State, &last_tagged, &tmp_player.Kills, &last_kill, &tmp_player.Cures, &tmp_player.Revives, &tmp_player.Extensions)
tmp_player.Last_tagged, _ = time.Parse(time_format, last_tagged)
tmp_player.Last_kill, _ = time.Parse(time_format, last_kill)
if err != nil {
return Player{}, err
}
return tmp_player, nil
}
func save_player(player Player) {
tmp_id := ""
row := db.QueryRow("SELECT id FROM players WHERE id = ?", player.Id)
err := row.Scan(&tmp_id)
var statement *sql.Stmt
if err != nil {
statement, _ = db.Prepare("INSERT INTO players (id, name, password, state, last_tagged, kills, last_kill, cures, revives, extensions) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
last_tagged, _ := player.Last_tagged.MarshalText()
last_kill, _ := player.Last_kill.MarshalText()
statement.Exec(player.Id, player.Name, player.password, player.State, last_tagged, player.Kills, last_kill, player.Cures, player.Revives, player.Extensions)
} else {
statement, err = db.Prepare("UPDATE players SET id = ?, name = ?, password = ?, state = ?, last_tagged = ?, kills = ?, last_kill = ?, cures = ?, revives = ?, extensions = ? WHERE id = ?")
last_tagged, _ := player.Last_tagged.MarshalText()
last_kill, _ := player.Last_kill.MarshalText()
statement.Exec(player.Id, player.Name, player.password, player.State, last_tagged, player.Kills, last_kill, player.Cures, player.Revives, player.Extensions, player.Id)
}
}
// @title DCU Games Society Humans Vs Zombies // @title DCU Games Society Humans Vs Zombies
// @version 1.0 // @version 1.0
// @description This is the Swagger documentation for DCU Games Society's 2022 Humans Vs Zombies event. // @description This is the Swagger documentation for DCU Games Society's 2022 Humans Vs Zombies event.
@ -19,33 +106,269 @@ import (
// @host // @host
// @BasePath / // @BasePath /
func handleRequests() { func handleRequests() {
myRouter := mux.NewRouter().StrictSlash(true) router := mux.NewRouter().StrictSlash(false)
myRouter.HandleFunc("/", homePage) router.Path("/me").Methods(http.MethodGet).HandlerFunc(me)
myRouter.PathPrefix("/docs/").Handler(httpSwagger.WrapHandler) router.Path("/login").Methods(http.MethodPost).HandlerFunc(login)
router.Path("/tag/{target}").Methods(http.MethodGet).HandlerFunc(tag)
router.Path("/kill/{target}").Methods(http.MethodGet).HandlerFunc(kill)
router.Path("/cure/{target}").Methods(http.MethodGet).HandlerFunc(cure)
router.Path("/revive/{target}").Methods(http.MethodGet).HandlerFunc(revive)
router.PathPrefix("/docs/").Handler(httpSwagger.WrapHandler)
log.Fatal(http.ListenAndServe(":8000", myRouter)) log.Fatal(http.ListenAndServe(":8000", router))
} }
// @Summary Home // @Summary Login
// @Description Home page // @Description Login
// @Produce json // @Produce json
// @Success 200 // @Accept json
// @Router / [get] // @Param info body Login true "Player login"
func homePage(w http.ResponseWriter, r *http.Request) { // @Success 200 {object} Player
player := Player{ // @Failure 400
id: 0, // @Failure 403
name: "Malachy Byrne", // @Router /login [post]
state: 4, func login(w http.ResponseWriter, r *http.Request) {
pin: "1234", l := Login{}
infection_time: time.Now(),
kills: 0, if err := json.NewDecoder(r.Body).Decode(&l); err != nil {
last_kill: time.Now(), fmt.Println(err)
http.Error(w, "Error decoding response object", http.StatusBadRequest)
return
} }
fmt.Println(player)
w.Header().Set("Content-Type", "application/json") players := get_all_players()
for _, player := range players {
if (player.Name == l.Name && player.login(l.Pass)) {
session, _ := store.Get(r, "session")
session.Values["userID"] = player.Id
session.Save(r, w)
http.Redirect(w, r, "/me", http.StatusFound)
return
}
}
http.Error(w, "Username or password incorrect", http.StatusForbidden)
}
// @Summary Tag
// @Description Tag a human as a zombie. Gives target the infected state if user is a zombie or core zombie.
// @Produce plain
// @Param target path string true "Target ID"
// @Success 200
// @Failure 401 {string} string "User is not logged in"
// @Failure 403 {string} string "Tagger is not a zombie"
// @Failure 404 {string} string "Target does not exist"
// @Failure 409 {string} string "Target is not human"
// @Router /tag [get]
func tag(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
target_id := vars["target"]
sess, _ := store.Get(r, "session")
id, ok := sess.Values["userID"]
if !ok {
http.Error(w, "User not logged in", http.StatusUnauthorized)
return
}
player, _ := get_player(id.(string))
if (player.State != CoreZombie && player.State != Zombie) {
http.Error(w, "Tagger is not a zombie", http.StatusForbidden)
return
}
target, err := get_player(target_id)
if (err != nil) {
http.Error(w, "Target not found", http.StatusNotFound)
return
}
if (target.State != Human) {
http.Error(w, "Target not human", http.StatusConflict)
return
}
target.State = InfectedHuman
target.Last_tagged = time.Now()
player.Last_kill = time.Now()
player.Kills += 1
save_player(target)
save_player(player)
fmt.Fprintf(w, "Successfully tagged target")
}
// @Summary Kill
// @Description Kills a zombie if user is authenticated as a human. Gives zombie target the stunned state
// @Produce plain
// @Param target path string true "Target ID"
// @Success 200
// @Failure 401 {string} string "User is not logged in"
// @Failure 403 {string} string "Killer is not a human"
// @Failure 404 {string} string "Target does not exist"
// @Failure 409 {string} string "Target is not a zombie"
// @Router /kill [get]
func kill(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
target_id := vars["target"]
sess, _ := store.Get(r, "session")
id, ok := sess.Values["userID"]
if !ok {
http.Error(w, "User not logged in", http.StatusUnauthorized)
return
}
tagger, _ := get_player(id.(string))
if (tagger.State != Human) {
http.Error(w, "Killer is not a human", http.StatusForbidden)
return
}
target, err := get_player(target_id)
if err != nil {
http.Error(w, "Target not found", http.StatusNotFound)
return
}
if (target.State != Zombie && target.State != CoreZombie) {
http.Error(w, "Target not a zombie", http.StatusConflict)
}
target.State = StunnedZombie
target.Last_tagged = time.Now()
tagger.Last_kill = time.Now()
tagger.Kills += 1
save_player(target)
save_player(tagger)
fmt.Fprintln(w, "Successfully killed target")
}
// @Summary Me
// @Description Shows user information
// @Produce json
// @Success 200 {object} Player
// @Failure 401 {string} string "User is not logged in"
// @Router /me [get]
func me (w http.ResponseWriter, r *http.Request) {
sess, _ := store.Get(r, "session")
id, ok := sess.Values["userID"]
if !ok {
http.Error(w, "User not logged in", http.StatusUnauthorized)
return
}
player, _ := get_player(id.(string))
json.NewEncoder(w).Encode(player) json.NewEncoder(w).Encode(player)
} }
// @Summary Cure
// @Description Cures a zombie or infected human
// @Produce plain
// @Success 200
// @Failure 401 {string} string "User is not logged in"
// @Failure 403 {string} string "No cures available"
// @Failure 404 {string} string "Target does not exist"
// @Failure 409 {string} string "Target is not a zombie"
// @Param target path string true "Target ID"
// @Router /cure [get]
func cure(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
target_id := vars["target"]
sess, _ := store.Get(r, "session")
id, ok := sess.Values["userID"]
if !ok {
http.Error(w, "User not logged in", http.StatusUnauthorized)
return
}
target, err := get_player(target_id)
if err != nil {
http.Error(w, "Target does not exist", http.StatusNotFound)
return
}
player, _ := get_player(id.(string))
if player.Cures == 0 {
http.Error(w, "Not enough cures", http.StatusForbidden)
return
}
if (target.State != Zombie && target.State != StunnedZombie && target.State != InfectedHuman) {
http.Error(w, "Target is not a zombie", http.StatusConflict)
return
}
target.State = Human
player.Cures -= 1
save_player(target)
save_player(player)
}
// @Summary Revive
// @Description Revives a stunned zombie
// @Produce plain
// @Success 200
// @Failure 401 {string} string "User is not logged in"
// @Failure 403 {string} string "No revives available"
// @Failure 404 {string} string "Target does not exist"
// @Failure 409 {string} string "Target is not stunned"
// @Param target path string true "Target ID"
// @Router /revive [get]
func revive(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
target_id := vars["target"]
sess, _ := store.Get(r, "session")
id, ok := sess.Values["userID"]
if !ok {
http.Error(w, "User not logged in", http.StatusUnauthorized)
return
}
target, err := get_player(target_id)
if err != nil {
http.Error(w, "Target does not exist", http.StatusNotFound)
return
}
player, _ := get_player(id.(string))
if player.Revives == 0 {
http.Error(w, "Not enough revives", http.StatusForbidden)
return
}
if (target.State != StunnedZombie) {
http.Error(w, "Target is not stunned", http.StatusConflict)
return
}
target.State = Zombie
player.Revives -= 1
save_player(target)
save_player(player)
}
func main() { func main() {
db, _ = sql.Open("sqlite3", "players.db")
statement, err := db.Prepare("CREATE TABLE IF NOT EXISTS players (id VARCHAR(7) PRIMARY KEY, name VARCHAR(64), password varchar(128), state INTEGER, last_tagged VARCHAR(25), kills INTEGER, last_kill VARCHAR(25), cures INTEGER, revives INTEGER, extensions INTEGER)")
if err != nil {
fmt.Println(err)
} else {
fmt.Println("table created successfully")
}
statement.Exec()
player1 := new_player("player1", "password1", CoreZombie)
player2 := new_player("player2", "password2", Zombie)
player3 := new_player("player3", "password3", StunnedZombie)
player4 := new_player("player4", "password4", InfectedHuman)
player5 := new_player("player5", "password5", Human)
player6 := new_player("player6", "password6", Dead)
save_player(player1)
save_player(player2)
save_player(player3)
save_player(player4)
save_player(player5)
save_player(player6)
go update()
handleRequests() handleRequests()
} }

View File

@ -1,25 +1,73 @@
package main package main
import ( import (
"fmt"
"time" "time"
"golang.org/x/crypto/bcrypt"
"github.com/google/uuid"
) )
type State int type State int
const ( const (
CoreZombie State = iota + 1 CoreZombie State = iota
Zombie Zombie
StunnedCoreZombie
StunnedZombie
InfectedHuman InfectedHuman
Human Human
Dead Dead
) )
type Player struct { type Player struct {
id int `json:"id"` Id string `json:"id"`
name string `json:"name"` Name string `json:"name"`
state State `json:"state"` password string
pin string `json:"pin"` State State `json:"state"`
infection_time time.Time `json:"infection_time"` Last_tagged time.Time `json:"last_tagged"`
kills int `json:"kills"` Kills int `json:"kills"`
last_kill time.Time `json:"last_kill"` Last_kill time.Time `json:"last_kill"`
Cures int `json:"cures"`
Revives int `json:"revives"`
Extensions int `json:"extensions"`
}
type Login struct {
Name string `json:"name"`
Pass string `json:"password"`
}
func gen_pass(password string) (string) {
password_bytes := []byte(password)
hashed_bytes, _ := bcrypt.GenerateFromPassword(password_bytes, bcrypt.MinCost)
return string(hashed_bytes)
}
func new_player(name string, password string, state State) (Player) {
new_player := Player{
Id: uuid.New().String()[0:7],
Name: name,
password: gen_pass(password),
State: state,
Last_tagged: time.Now(),
Kills: 0,
Last_kill: time.Now(),
Cures: 3,
Revives: 3,
Extensions: 3,
}
return new_player
}
func (p *Player) login (password string) (bool) {
succ := bcrypt.CompareHashAndPassword([]byte(p.password), []byte(password))
if (succ == nil) {
return true
} else {
fmt.Println(succ)
return false
}
} }