defining some more persistence stuff

slack
Jordan Orelli 10 years ago
parent 31e70ce85c
commit 95a05d843f

@ -235,7 +235,7 @@ var winCommand = &Command{
name: "win", name: "win",
help: "win the game.", help: "win the game.",
handler: func(conn *Connection, args ...string) { handler: func(conn *Connection, args ...string) {
conn.Win() conn.Win("win-command")
}, },
} }

@ -5,6 +5,7 @@ import (
) )
type Game struct { type Game struct {
id Id
start time.Time start time.Time
end time.Time end time.Time
winner string winner string
@ -13,7 +14,7 @@ type Game struct {
func gamesTable() { func gamesTable() {
stmnt := `create table if not exists games ( stmnt := `create table if not exists games (
id integer not null primary key autoincrement, id text not null,
start text not null, start text not null,
end text, end text,
winner text, winner text,
@ -26,6 +27,7 @@ func gamesTable() {
func NewGame() *Game { func NewGame() *Game {
game := &Game{ game := &Game{
id: NewId(),
start: time.Now(), start: time.Now(),
} }
if err := game.Create(); err != nil { if err := game.Create(); err != nil {
@ -37,9 +39,9 @@ func NewGame() *Game {
func (g *Game) Create() error { func (g *Game) Create() error {
_, err := db.Exec(` _, err := db.Exec(`
insert into games insert into games
(start) (id, start)
values values
(?) (?, ?)
;`, g.start) ;`, g.id.String(), g.start)
return err return err
} }

@ -0,0 +1,29 @@
package main
import (
"crypto/md5"
"os"
)
var global struct {
hostname string
machineId []byte
pid int
idCounter uint32
}
func init() {
global.pid = os.Getpid()
var err error
global.hostname, err = os.Hostname()
if err != nil {
panic("failed to get hostname: " + err.Error())
}
hw := md5.New()
if _, err := hw.Write([]byte(global.hostname)); err != nil {
panic("unable to md5 hostname: " + err.Error())
}
global.machineId = make([]byte, 3)
copy(global.machineId, hw.Sum(nil))
}

55
id.go

@ -0,0 +1,55 @@
package main
import (
"encoding/binary"
"fmt"
"sync/atomic"
"time"
)
// NewObjectId returns a new unique ObjectId.
// This function causes a runtime error if it fails to get the hostname
// of the current machine.
func NewId() Id {
b := make([]byte, 12)
// Timestamp, 4 bytes, big endian
binary.BigEndian.PutUint32(b, uint32(time.Now().Unix()))
b[4] = global.machineId[0]
b[5] = global.machineId[1]
b[6] = global.machineId[2]
// Pid, 2 bytes, specs don't specify endianness, but we use big endian.
b[7] = byte(global.pid >> 8)
b[8] = byte(global.pid)
// Increment, 3 bytes, big endian
i := atomic.AddUint32(&global.idCounter, 1)
b[9] = byte(i >> 16)
b[10] = byte(i >> 8)
b[11] = byte(i)
return Id(b)
}
// Id is used for tagging each incoming http request for logging
// purposes. The actual implementation is just the ObjectId implementation
// found in launchpad.net/mgo/bson. This will most likely change and evolve
// into its own format.
type Id string
func (id Id) String() string {
return fmt.Sprintf("%x", string(id))
}
// Time returns the timestamp part of the id.
// It's a runtime error to call this method with an invalid id.
func (id Id) Time() time.Time {
secs := int64(binary.BigEndian.Uint32(id.byteSlice(0, 4)))
return time.Unix(secs, 0)
}
// byteSlice returns byte slice of id from start to end.
// Calling this function with an invalid id will cause a runtime panic.
func (id Id) byteSlice(start, end int) []byte {
if len(id) != 12 {
panic(fmt.Sprintf("Invalid Id: %q", string(id)))
}
return []byte(string(id)[start:end])
}

@ -128,7 +128,7 @@ func (c *Connection) NextBomb() time.Duration {
func (c *Connection) MadeKill(victim *Connection) { func (c *Connection) MadeKill(victim *Connection) {
c.kills += 1 c.kills += 1
if c.kills == 3 { if c.kills == 3 {
c.Win() c.Win("military")
} }
} }
@ -163,11 +163,11 @@ func (c *Connection) Withdraw(n int64) {
func (c *Connection) Deposit(n int64) { func (c *Connection) Deposit(n int64) {
c.money += n c.money += n
if c.money >= 25000 { if c.money >= 25000 {
c.Win() c.Win("economic")
} }
} }
func (c *Connection) Win() { func (c *Connection) Win(method string) {
for conn, _ := range connected { for conn, _ := range connected {
fmt.Fprintf(conn, "player %s has won.\n", c.PlayerName()) fmt.Fprintf(conn, "player %s has won.\n", c.PlayerName())
conn.Close() conn.Close()

Loading…
Cancel
Save