ludic/packages/ludic.net/state.ludic

138 lines
5.2 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,
back: []NetMsg, # the queue's other list, filled by a flush and swapped in
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()
@max(64) net__fpool: []NetFact = net__fpool__new() # the facts' records, taken in turn (pool.ludic)
net__fat: int = 0
net__watch_url: string = "" # the room's address, made once per room
net__seen: []string = new []string # guests already punched for
net__free: []NetMsg = new []NetMsg # sent and taken (or stale): made again, never new (pool.ludic)
net__ina: []NetMessage = new []NetMessage # the inbox's records, two halves
net__inb: []NetMessage = new []NetMessage
net__inn: int = 0
net__in_on_b: bool = false
net__sb: []byte = buffer(32) # a relay hello's or a STUN request's bytes
net__wr: NetMessage = null # net_written's, kept
net__tsb: StrBuf = sb_new(NET_MTU) # a text read out of a message, interned (a name comes every frame)
net__ttb: StrTable = strs_new(4096)
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__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
p.back = new []NetMsg
push(out, p)
}
return out
}