Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

final submission for David and Joseph #17

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
199 changes: 90 additions & 109 deletions README.md

Large diffs are not rendered by default.

Binary file added assets/.DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Assets that are used will be housed here
Binary file added assets/biomes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/biomes.psd
Binary file not shown.
Binary file added assets/characters.psd
Binary file not shown.
Binary file added assets/moresprites.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/overworld.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/pepe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/player.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/player2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/player_sprites.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/player_sprites.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/pokemon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sprites.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions css/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
body {
background-color: black;
}

.viewport-container {
width: 100%;
text-align: center;
}

.viewport {
display: inline;
}

.debug-canvas {
vertical-align: top;
}
37 changes: 37 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
PROJ_DIR=$(pwd)
BUILD_DIR=$PROJ_DIR/build
DEPLOY_DIR=$PROJ_DIR/../procedural_pokemon_build
set -o errexit

printf "Deploying from $PROJ_DIR\n"
printf "Building...\n"
git checkout master 1>/dev/null 2>/dev/null
git pull origin master 1>/dev/null 2>/dev/null
npm run build > /dev/null

printf "Creating deploy environment...\n"
if [ -d $DEPLOY_DIR ]; then
rm -rf $DEPLOY_DIR > /dev/null
printf "Deploy directory already exists, removing...\n"
fi

mkdir -p $DEPLOY_DIR
cp -R $BUILD_DIR/* $DEPLOY_DIR
cp -R $PROJ_DIR/assets $DEPLOY_DIR
cp $PROJ_DIR/index.html $DEPLOY_DIR
cp -R $PROJ_DIR/css $DEPLOY_DIR
cd $DEPLOY_DIR

printf "Deploying...\n"
git init > /dev/null
git remote add origin [email protected]:davlia/procedural-pokemon.git > /dev/null
git checkout -b gh-pages 1>/dev/null 2>/dev/null
git add -A > /dev/null
git commit -am "deploying" > /dev/null
git push -f origin gh-pages 1>/dev/null 2>/dev/null

printf "Cleaning up...\n"
rm -rf $BUILD_DIR
rm -rf $DEPLOY_DIR

printf "Success!\n"
18 changes: 18 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>Procedural Pokemon</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<script src="bundle.js"></script>
<div>
<form>
Num Areas:<br>
<input type="text" name="areas" placeholder='num areas'>
<br>
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>
31 changes: 31 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"scripts": {
"start": "webpack-dev-server --hot --inline",
"build": "webpack",
"deploy": "./deploy.sh"
},
"gh-pages-deploy": {
"prep": [
"build"
],
"noprompt": true
},
"dependencies": {
"dat-gui": "^0.5.0",
"express": "^4.15.2",
"gl-matrix": "^2.3.2",
"seedrandom": "^2.4.3",
"stats-js": "^1.0.0-alpha1"
},
"devDependencies": {
"babel-core": "^6.18.2",
"babel-loader": "^6.2.8",
"babel-preset-es2015": "^6.18.0",
"colors": "^1.1.2",
"gh-pages-deploy": "^0.4.2",
"simple-git": "^1.65.0",
"webpack": "1.14.0",
"webpack-dev-server": "^1.16.3",
"webpack-glsl-loader": "^1.0.1"
}
}
2 changes: 2 additions & 0 deletions server/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
all:
go run *.go
33 changes: 33 additions & 0 deletions server/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package main

import "github.com/gorilla/websocket"

// Client encapsulates all player connection contexts
type Client struct {
Conn *websocket.Conn
ID int32
}

// NewClient creates a new client
func NewClient(conn *websocket.Conn, id int32) *Client {
c := &Client{
Conn: conn,
ID: id,
}
return c
}

// ReadJSON forwards the ReadJSON call
func (C *Client) ReadJSON(v interface{}) error {
return C.Conn.ReadJSON(v)
}

// WriteJSON forwards the WriteJSON call
func (C *Client) WriteJSON(v interface{}) error {
return C.Conn.WriteJSON(v)
}

// Close forwards the Close call
func (C *Client) Close() error {
return C.Conn.Close()
}
115 changes: 115 additions & 0 deletions server/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package main

import (
"log"
"math/rand"

"github.com/gorilla/websocket"
)

// Controller handles all ws connection events and is the driver module
type Controller struct {
ReceiveChan chan InboundMessage
SendChan chan OutboundMessage
Clients map[int32]*Client
World World
}

// NewController creates a new controller
func NewController() Controller {
w := World{
Size: 512,
Seed: 0,
Agents: map[int32]Agent{},
}
c := Controller{
ReceiveChan: make(chan InboundMessage, 128),
SendChan: make(chan OutboundMessage, 128),
Clients: make(map[int32]*Client),
World: w,
}
return c
}

func (C *Controller) run() {
go C.handleInboundMessages()
go C.handleOutboundMessages()
}

func (C *Controller) handleInboundMessages() {
for {
msg := <-C.ReceiveChan
switch msg.Type {
case "init":
C.handleInit(msg)
case "update":
C.handleUpdate(msg)
default:
log.Printf("message unhandled: %+v\n", msg)
}
}
}

func (C *Controller) sendMessage(t string, data Data, id int32) {
send := OutboundMessage{
Type: t,
Data: data,
Receiver: id,
}
C.SendChan <- send
}

func (C *Controller) broadcastMessage(t string, data Data, sender int32) {
for id := range C.Clients {
if id == sender {
continue
}
C.sendMessage(t, data, id)
}
}

func (C *Controller) handleOutboundMessages() {
for {
msg := <-C.SendChan
client, ok := C.Clients[msg.Receiver]
if !ok {
log.Printf("error: could not find connection by id\n")
continue
}
client.WriteJSON(msg)
}
}

// AddConn adds connections to be tracked and listened to
func (C *Controller) AddConn(conn *websocket.Conn) {
id := C.nextID()
client := NewClient(conn, id)
C.Clients[id] = client
go C.readFromClient(client)
}

func (C *Controller) readFromClient(client *Client) {
for {
var msg InboundMessage
err := client.ReadJSON(&msg)
if err != nil {
log.Printf("Connection closed by %d\n", client.ID)
C.handleDisconnect(client.ID)
return
}
// TODO: this is sort of hacky IMO? should refactor in future
// Fill in the ID as part of the incoming message
msg.Sender = client.ID
C.ReceiveChan <- msg
}
}

func (C *Controller) nextID() int32 {
// TODO: do something else here that doesn't put your 4 years of higher education to fucking shame
for {
id := rand.Int31()
if _, ok := C.Clients[id]; !ok {
return id
}
}
}
1 change: 1 addition & 0 deletions server/gameinstance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package main
61 changes: 61 additions & 0 deletions server/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package main

func (C *Controller) handleInit(msg InboundMessage) {
// Initialize newly connected user
p := Agent{
Type: "player",
Pos: Point{X: 256, Y: 256}, // Default spawn location is 10, 10 for now. We can change this later -- David
ID: msg.Sender,
SpriteID: "F",
Dir: "down",
}
C.World.Agents[msg.Sender] = p
init := Data{
Message: "alrighty, here you go",
Init: Init{C.World},
}

C.sendMessage("init", init, msg.Sender)

// Update all other players
u := Update{
Add: []Agent{p},
}
update := Data{
Message: "let's keep everyone on the same page",
Update: u,
}
C.broadcastMessage("add", update, msg.Sender)
}

func (C *Controller) handleUpdate(msg InboundMessage) {
// TODO: Apply state validation, more granular changes, copy by reference (maybe?)
// Apply update to server state
for _, p := range msg.Data.Update.Delta {
C.World.Agents[p.ID] = p
}

// Forward update to all players
d := Data{
Message: "catch up plz",
Update: msg.Data.Update,
}
C.broadcastMessage("update", d, msg.Sender)
}

func (C *Controller) handleDisconnect(id int32) {
// Remove the player from our server state and client from connections
removedPlayer := C.World.Agents[id]
delete(C.World.Agents, id)
delete(C.Clients, id)

// Update all other players
u := Update{
Delete: []Agent{removedPlayer},
}
d := Data{
Message: "catch up plz",
Update: u,
}
C.broadcastMessage("delete", d, -1)
}
70 changes: 70 additions & 0 deletions server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package main

import (
"fmt"
"log"
"net/http"
"os"
"time"

"github.com/gorilla/mux"
"github.com/gorilla/websocket"
)

var (
addr = ":8000"
upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
certFile = "./ssl/davidliao_me.crt"
keyFile = "./ssl/davidliao.me.key"
c = NewController()
)

func main() {
env := os.Getenv("environment")

go c.run()
r := mux.NewRouter()

r.HandleFunc("/health", health)
r.HandleFunc("/", health)
r.HandleFunc("/play", handleConnection)

s := http.Server{
Handler: r,
Addr: addr,
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Printf("Listening and serving on %s\n", addr)
if env == "production" {
log.Fatal(s.ListenAndServeTLS(certFile, keyFile))
} else {
log.Fatal(s.ListenAndServe())
}
}

// health reports 200 if services is up and running
func health(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "it's alive :O")
}

// handleConnection handles websocket requests from client
func handleConnection(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, "Method not allowed", 405)
return
}

conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
c.AddConn(conn)
}
Loading