<commit_before>package warserver

import (
	"container/list"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/Tactique/golib/connection"
	"github.com/Tactique/golib/logger"
	_ "github.com/mattn/go-sqlite3"
	"os"
	"strings"
)

const (
	NUM_PLAYERS = 2
)

type newGame struct {
	NumPlayers int
	cconn      *clientConnection
}

type localHandler func(message string, cconn *clientConnection)

type game_hub struct {
	gameRequests     chan *newGame
	uncommittedGames map[int]*game
	committedGames   *list.List
	connRegister     chan connection.Connection
	localHandlers    map[string]localHandler
}

type response struct {
	Status  int         `json:"status"`
	Payload interface{} `json:"payload"`
}

func CommandMarshal(cmd string, payload interface{}) []byte {
	body, err := json.Marshal(payload)
	if err != nil {
		logger.Warnf("Error marshalling json: ", err)
		return nil
	}
	return append([]byte(cmd+":"), body...)
}

func (gh *game_hub) handleWebsocket(message []byte, cconn *clientConnection) {
	cmds := strings.SplitN(string(message), ":", 2)
	if len(cmds) == 2 {
		if fun, ok := gh.localHandlers[cmds[0]]; ok {
			fun(cmds[1], cconn)
		} else {
			logger.Warnf("Unrecognized command: %s", cmds[0])
			cconn.toClient <- []byte("unrecognized:")
		}
	} else {
		logger.Errorf("Malformed command: %s", cmds)
	}
}

func (gh *game_hub) handleClientInfo(message string, cconn *clientConnection) {
	ci := clientInfo{}
	resp := response{0, nil}
	// I hate repeating this unmarshalling code, does Go allow something more general?
	err := json.Unmarshal([]byte(message), &ci)
	if err != nil {
		logger.Warnf("Error unmarshalling json: %s", err)
		return
	}
	userid, err := getClientIdFromToken(ci.Token)
	if err != nil {
		logger.Errorf("Error querying database: %s", err)
		resp.Status = -1
		cconn.toClient <- CommandMarshal("clientInfo", resp)
		return
	}
	ci.id = userid
	cconn.info = ci
	cconn.toClient <- CommandMarshal("clientInfo", resp)
}

func getClientIdFromToken(token string) (int, error) {
	dbPath := os.Getenv("DOMOROOT") + "/domoweb/db.sqlite3"
	db, err := sql.Open("sqlite3", dbPath)
	if err != nil {
		logger.Fatalf("%s", err)
	}
	defer db.Close()

	sql := fmt.Sprintf("select id, userid from interface_logindata where token='%s';", token)
	rows, err := db.Query(sql)
	if err != nil {
		return 0, err
	}
	var rowId int
	var userId int
	if rows.Next() {
		err := rows.Scan(&rowId, &userId)
		if err != nil {
			return 0, err
		}
	}
	if rows.Next() {
		return 0, errors.New("More than one entry returned in user query")
	}<commit_msg>Move database file to reflect webserver rename<commit_after>package warserver

import (
	"container/list"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/Tactique/golib/connection"
	"github.com/Tactique/golib/logger"
	_ "github.com/mattn/go-sqlite3"
	"os"
	"strings"
)

const (
	NUM_PLAYERS = 2
)

type newGame struct {
	NumPlayers int
	cconn      *clientConnection
}

type localHandler func(message string, cconn *clientConnection)

type game_hub struct {
	gameRequests     chan *newGame
	uncommittedGames map[int]*game
	committedGames   *list.List
	connRegister     chan connection.Connection
	localHandlers    map[string]localHandler
}

type response struct {
	Status  int         `json:"status"`
	Payload interface{} `json:"payload"`
}

func CommandMarshal(cmd string, payload interface{}) []byte {
	body, err := json.Marshal(payload)
	if err != nil {
		logger.Warnf("Error marshalling json: ", err)
		return nil
	}
	return append([]byte(cmd+":"), body...)
}

func (gh *game_hub) handleWebsocket(message []byte, cconn *clientConnection) {
	cmds := strings.SplitN(string(message), ":", 2)
	if len(cmds) == 2 {
		if fun, ok := gh.localHandlers[cmds[0]]; ok {
			fun(cmds[1], cconn)
		} else {
			logger.Warnf("Unrecognized command: %s", cmds[0])
			cconn.toClient <- []byte("unrecognized:")
		}
	} else {
		logger.Errorf("Malformed command: %s", cmds)
	}
}

func (gh *game_hub) handleClientInfo(message string, cconn *clientConnection) {
	ci := clientInfo{}
	resp := response{0, nil}
	// I hate repeating this unmarshalling code, does Go allow something more general?
	err := json.Unmarshal([]byte(message), &ci)
	if err != nil {
		logger.Warnf("Error unmarshalling json: %s", err)
		return
	}
	userid, err := getClientIdFromToken(ci.Token)
	if err != nil {
		logger.Errorf("Error querying database: %s", err)
		resp.Status = -1
		cconn.toClient <- CommandMarshal("clientInfo", resp)
		return
	}
	ci.id = userid
	cconn.info = ci
	cconn.toClient <- CommandMarshal("clientInfo", resp)
}

func getClientIdFromToken(token string) (int, error) {
	dbPath := os.Getenv("DOMOROOT") + "/webserver/db.sqlite3"
	db, err := sql.Open("sqlite3", dbPath)
	if err != nil {
		logger.Fatalf("%s", err)
	}
	defer db.Close()

	sql := fmt.Sprintf("select id, userid from interface_logindata where token='%s';", token)
	rows, err := db.Query(sql)
	if err != nil {
		return 0, err
	}
	var rowId int
	var userId int
	if rows.Next() {
		err := rows.Scan(&rowId, &userId)
		if err != nil {
			return 0, err
		}
	}
	if rows.Next() {
		return 0, errors.New("More than one entry returned in user query")
	}
{'fraction_non_alphanumeric': 0.1451581602949738, 'fraction_numerical': 0.005433727925480303, 'mean_word_length': 4.128358208955224, 'pattern_counts': {'":': 4, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1172611', 'n_tokens_mistral': 1934, 'n_tokens_neox': 1857, 'n_words': 470}