125 lines
4.4 KiB
Text
125 lines
4.4 KiB
Text
# state.ludic - the wire's numbers, a peer, a queued message, what came in, and the session
|
|
export const NET_MTU: int = 1200
|
|
export const NET_PEERS: int = 12 # a host: slot 0 unused, a guest each after; a guest: 0 is the host
|
|
export const NET_TIMEOUT: int = 10 # seconds of silence before a peer is gone
|
|
export const NET_HELLO: int = 1 # the one kind a stranger may send a host; every other is the game's
|
|
const NET_BEAT: int = 0 # a heartbeat, never delivered
|
|
|
|
export const NET_IDLE: int = 0
|
|
export const NET_HOSTING: int = 1
|
|
export const NET_JOINING: int = 2
|
|
export const NET_JOINED: int = 3
|
|
export const NET_LOST: int = 4
|
|
|
|
# a message on its way out, kept until acknowledged when it is reliable
|
|
property NetMsg {
|
|
kind: int = 0,
|
|
rel: bool = false,
|
|
id: int = 0,
|
|
sent: float = 0.0, # net seconds it was last sent; -1 never
|
|
len: int = 0,
|
|
made: float = 0.0, # net seconds it was queued
|
|
data: []byte
|
|
}
|
|
|
|
property NetPeer {
|
|
on: bool = false,
|
|
ip: int = 0,
|
|
port: int = 0,
|
|
pid: int = 0,
|
|
heard: float = 0.0, # net seconds of the last packet from it
|
|
next_id: int = 1, # the next reliable id to send it
|
|
recv_id: int = 0, # the highest reliable id taken from it, in order
|
|
acked: int = 0, # the highest id it has taken from us
|
|
ack_due: bool = false,
|
|
queue: []NetMsg,
|
|
closing: bool = false, # let go once it has taken close_id
|
|
close_id: int = 0,
|
|
close_t: float = 0.0 # ... or at this net time, whichever comes first
|
|
}
|
|
|
|
# a message that came in, in order: read it with net_read(m) and nr_*
|
|
export property NetMessage {
|
|
slot: int = 0, # the peer slot it came from
|
|
from: int = 0, # the sender's pid, as its header says
|
|
kind: int = 0,
|
|
len: int = 0,
|
|
data: []byte
|
|
}
|
|
|
|
export state NetState {
|
|
net__cfg: NetConfig = new NetConfig
|
|
net__facts: Queue<NetFact> = net__facts__new()
|
|
net__seen: []string = new []string # guests already punched for
|
|
net__punch_ip: words = null
|
|
net__punch_port: words = null
|
|
net__punch_left: words = null
|
|
net__punch_t: float = 0.0
|
|
net__punch_b: []byte = null # the punch itself, "MP" and two zeros, made once
|
|
net__relay_ip: int = 0
|
|
net__relay_port: int = 0
|
|
net__via_relay: bool = false # a guest talking to its host through the relay
|
|
net__from_ip: int = 0
|
|
net__from_port: int = 0
|
|
net__r_state: int = 0
|
|
net__r_role: int = 0 # 1 host, 2 guest
|
|
net__r_t: float = 0.0
|
|
net__r_tries: int = 0
|
|
net__pub_ip: int = 0
|
|
net__pub_port: int = 0
|
|
net__room: string = "" # the host's room code, or the one a guest asked for
|
|
net__http: int = 0
|
|
net__poll_t: float = 0.0
|
|
net__relay_t: float = 0.0
|
|
net__dial_heard: float = 0.0
|
|
net__why: int = 0
|
|
net__state: int = 0
|
|
net__sock: int = 0
|
|
net__time: float = 0.0
|
|
net__token: int = 0
|
|
net__my_pid: int = 0
|
|
net__next_pid: int = 2
|
|
net__peers: []NetPeer = net__peers_new()
|
|
net__in: []byte = buffer(NET_MTU + 64)
|
|
net__out: []byte = buffer(NET_MTU + 64)
|
|
net__wb: []byte = buffer(NET_MTU) # the message being written
|
|
net__wl: int = 0
|
|
net__rb: []byte = buffer(NET_MTU) # the message being read
|
|
net__rl: int = 0
|
|
net__rp: int = 0
|
|
net__rbad: bool = false
|
|
net__tb: []byte = buffer(NET_MTU) # text read out of a message, through one scratch buffer
|
|
net__hello_b: []byte = buffer(NET_MTU) # the game's hello, sent again on every dial
|
|
net__hello_l: int = 0
|
|
net__hello_t: float = 0.0 # seconds since it went; -1 not yet
|
|
net__wait_more: int = 0 # extra seconds a slow host is given (a map switch, a matchmaker)
|
|
net__beat_t: float = 0.0
|
|
net__join_ip: int = 0
|
|
net__join_port: int = 0
|
|
net__code_ip: int = 0
|
|
net__code_port: int = 0
|
|
net__bytes_out: int = 0
|
|
net__kind_out: words = null
|
|
net__inbox: Queue<NetMessage> = net__inbox__new()
|
|
net__stun_ip: int = 0
|
|
net__stun_port: int = 0
|
|
net__txn: words = words(3)
|
|
net__dice: Rng = null
|
|
}
|
|
|
|
export function net_inbox(net_st: NetState) -> Queue<NetMessage> {
|
|
return net_st.net__inbox
|
|
}
|
|
|
|
function net__facts__new() -> Queue<NetFact> { return queue_new("net.facts") }
|
|
function net__inbox__new() -> Queue<NetMessage> { return queue_new("net.inbox") }
|
|
# every peer slot, each with its own queue
|
|
function net__peers_new() -> []NetPeer {
|
|
let out = new []NetPeer
|
|
for i in 0 .. NET_PEERS {
|
|
let p = new NetPeer
|
|
p.queue = new []NetMsg
|
|
push(out, p)
|
|
}
|
|
return out
|
|
}
|