<commit_before>package warserver

import (
    "fmt"
    "github.com/gorilla/websocket"
    "io"
    "net"
    "net/http"
    "strconv"
    "strings"
    "warserver/logger"
    "github.com/DomoCo/connection"
)

const (
    RECV_BUF_LEN = 1024
)

type websocketHandler interface {
    handleWebsocket(message []byte, cconn *clientConnection)
}

type clientInfo struct {
    Id int
}

type clientConnection struct {
    conn connection.Connection
    currentHandler websocketHandler
    handlers chan websocketHandler
    toClient chan []byte
    info clientInfo
}

type serverConnection struct {
    conn connection.Connection
}

type pipe struct {
    wsRecv chan []byte
    sockRecv chan []byte
}

type proxy struct {
    proxyConns []*clientConnection
    server *serverConnection
}

func (p *proxy) slotClientConnection(slot int, cconn *clientConnection) {
    p.proxyConns[slot] = cconn;
}

func (p *proxy) removeClientConnection(pos int) {
    j := pos + 1
    copy(p.proxyConns[pos:], p.proxyConns[j:])
    for k, n := len(p.proxyConns) - j + pos, len(p.proxyConns); k < n; k ++ {
        p.proxyConns[k] = nil // or the zero value of T
    } // for k
    p.proxyConns = p.proxyConns[:len(p.proxyConns) - j + pos]
}

func (p *proxy) handleWebsocket(message []byte, cconn *clientConnection) {
    message = appendClientInfo(message, cconn.info)
    logger.Infof("Proxying message from client: %s", message)
    err := p.server.conn.Write(message)
    if err != nil {
        logger.Errorf("Error while writing to socket: %s", err)
    }
}

func appendClientInfo(message []byte, info clientInfo) []byte {
    // This will be disagreed with...
    clientIdStr := strconv.Itoa(info.Id)
    return append(message, []byte(":" + clientIdStr)...)
}

func (p *proxy) serverReadPump() {
    defer func() {
        p.server.conn.Close()
    }()
    for {
        msg, err := p.server.conn.Read()
        if err != nil {
            logger.Errorf("Error while reading from socket: %s", err)
            break
        }
        logger.Debugf("Received %s from socket", msg)
        p.broadcast(msg)
    }
}

func (p *proxy) broadcast(message []byte) {
    for i := 0; i < len(p.proxyConns); i++ {
        p.proxyConns[i].toClient <- message
    }
}

func (p *proxy) sendInitialGameInfo() {
    // I'll send basically this once the server can accept it
    message := "new:{\"uids\": ["
    for i := 0; i < len(p.proxyConns); i++ {
        message = message + strconv.Itoa(p.proxyConns[i].info.Id)<commit_msg>Move player ID to after command, for ease of parsing<commit_after>package warserver

import (
    "fmt"
    "github.com/gorilla/websocket"
    "io"
    "net"
    "net/http"
    "strconv"
    "strings"
    "warserver/logger"
    "github.com/DomoCo/connection"
)

const (
    RECV_BUF_LEN = 1024
)

type websocketHandler interface {
    handleWebsocket(message []byte, cconn *clientConnection)
}

type clientInfo struct {
    Id int
}

type clientConnection struct {
    conn connection.Connection
    currentHandler websocketHandler
    handlers chan websocketHandler
    toClient chan []byte
    info clientInfo
}

type serverConnection struct {
    conn connection.Connection
}

type pipe struct {
    wsRecv chan []byte
    sockRecv chan []byte
}

type proxy struct {
    proxyConns []*clientConnection
    server *serverConnection
}

func (p *proxy) slotClientConnection(slot int, cconn *clientConnection) {
    p.proxyConns[slot] = cconn;
}

func (p *proxy) removeClientConnection(pos int) {
    j := pos + 1
    copy(p.proxyConns[pos:], p.proxyConns[j:])
    for k, n := len(p.proxyConns) - j + pos, len(p.proxyConns); k < n; k ++ {
        p.proxyConns[k] = nil // or the zero value of T
    } // for k
    p.proxyConns = p.proxyConns[:len(p.proxyConns) - j + pos]
}

func (p *proxy) handleWebsocket(message []byte, cconn *clientConnection) {
    message = appendClientInfo(message, cconn.info)
    logger.Infof("Proxying message from client: %s", message)
    err := p.server.conn.Write(message)
    if err != nil {
        logger.Errorf("Error while writing to socket: %s", err)
    }
}

func appendClientInfo(message []byte, info clientInfo) []byte {
    splitMsg := strings.SplitN(string(message), ":", 2)
    // This will be disagreed with...
    clientIdStr := strconv.Itoa(info.Id)
    return append([]byte(splitMsg[0]), []byte(":" + clientIdStr + ":" + splitMsg[1])...)
}

func (p *proxy) serverReadPump() {
    defer func() {
        p.server.conn.Close()
    }()
    for {
        msg, err := p.server.conn.Read()
        if err != nil {
            logger.Errorf("Error while reading from socket: %s", err)
            break
        }
        logger.Debugf("Received %s from socket", msg)
        p.broadcast(msg)
    }
}

func (p *proxy) broadcast(message []byte) {
    for i := 0; i < len(p.proxyConns); i++ {
        p.proxyConns[i].toClient <- message
    }
}

func (p *proxy) sendInitialGameInfo() {
    // I'll send basically this once the server can accept it
    message := "new:{\"uids\": ["
    for i := 0; i < len(p.proxyConns); i++ {
        message = message + strconv.Itoa(p.proxyConns[i].info.Id)
{'fraction_non_alphanumeric': 0.1349190875414311, 'fraction_numerical': 0.003314486254630532, 'mean_word_length': 2.857142857142857, 'pattern_counts': {'":': 6, '<': 11, '<?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': '884484', 'n_tokens_mistral': 1736, 'n_tokens_neox': 1705, 'n_words': 446}