# room.ludic - a party across two home routers. The host registers its outside and inside # addresses with the matchmaker and is given a six-letter room code; a guest hands over the code # and its own addresses and gets the host's back. Behind one router, the inside addresses. const NET_R_IDLE: int = 0 const NET_R_STUN: int = 1 # asking what this machine looks like from outside const NET_R_REGISTER: int = 2 # the host: asking for a room const NET_R_ROOM: int = 3 # the host: registered, watching for guests const NET_R_ASK: int = 4 # a guest: asking the room for the host const NET_R_DONE: int = 5 # a guest: the hello is on its way # room codes are on when the game named a matchmaker export function net_room_on(net_st: NetState) -> bool { return len(net__conf(net_st).signal_url) > 0 } export function net_room(net_st: NetState) -> string { return net_st.net__room } export function net_room_asking(net_st: NetState) -> bool { return net_st.net__r_state == NET_R_STUN or net_st.net__r_state == NET_R_ASK } # the host (after net_host or net_become_host): a room at the matchmaker, if there is one export function net_room_host(net_st: mut NetState) -> void { if not net_room_on(net_st) { return } net_st.net__r_role = 1 net_st.net__room = "" net_st.net__seen = new []string net__stun_begin(net_st) } # a guest by room code: the matchmaker's answer brings the host's address (the hello is set first) export function net_room_join(net_st: mut NetState, code: string) -> bool { if not net_room_on(net_st) { net_st.net__why = NET_WHY_NO_MATCHMAKER return false } if not net__socket(net_st) { return false } net_st.net__r_role = 2 net_st.net__room = Text.upper(code) net_st.net__wait_more = 20 # the matchmaker answers before the host does net__wait_for_host(net_st) net__stun_begin(net_st) return true } function net__stun_begin(net_st: mut NetState) -> void { net_st.net__r_state = NET_R_STUN net_st.net__r_t = 0.0 net_st.net__r_tries = 0 net_st.net__pub_ip = 0 net_st.net__pub_port = 0 if net__conf(net_st).no_stun { net_st.net__r_tries = 3 return } net__stun_send(net_st) } function net__room_body(net_st: NetState, role_key: string) -> string { var pub = "" if net_st.net__pub_ip != 0 { pub = net__addr_text(net_st.net__pub_ip, net_st.net__pub_port) } return "{\"" + role_key + "\": \"" + pub + "\", \"local\": \"" + net__local_text(net_st) + "\"}" } function net__json_str(v: Val, key: string) -> string { if v == null or value_has(v, key) == 0 { return "" } return value_as_str(value_get(v, key)) } function net__addr_text(ip: int, port: int) -> string { return `{Udp.ip_text(ip)}:{port}` } function net__local_text(net_st: NetState) -> string { var ip = NetSocket.local_ip() if ip == 0 { ip = Udp.ip("127.0.0.1") } return net__addr_text(ip, net_port(net_st)) }