# 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 = 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 = 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 { return net_st.net__inbox } function net__facts__new() -> Queue { return queue_new("net.facts") } function net__inbox__new() -> Queue { 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 }