From 14374433558e59e5a338627211c17187352e7934 Mon Sep 17 00:00:00 2001 From: Sketch <75850871+SketchMaster2001@users.noreply.github.com> Date: Thu, 9 Nov 2023 19:12:47 -0500 Subject: [PATCH] Add schema.sql and update README --- README.md | 15 +++- common/ip_address.go | 2 - database/login.go | 10 ++- gpcm/friend.go | 2 - gpcm/main.go | 7 ++ schema.sql | 200 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 228 insertions(+), 8 deletions(-) create mode 100644 schema.sql diff --git a/README.md b/README.md index 8c5b178..47ef4dc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # wwfc -WiiLink Wi-Fi Connection aims to be an open source server replacement for Nintendo Wi-Fi Connection. +WiiLink Wi-Fi Connection aims to be an open source server replacement for Nintendo Wi-Fi Connection. Currently, a work in progress + +## Current Support +- Matchmaking (No server sorting yet) +- Adding Friends + +## Setup +You will need: +- PostgreSQL + +1. Create a PostgreSQL database. Note the database name, username, and password. +2. Use the `schema.sql` found in the root of this repo and import it into your PostgreSQL database. +3. Copy `config-example.xml` to `config.xml` and insert all the correct data. +4. Run `go build`. The resulting executable `wwfc` is the executable of the server. diff --git a/common/ip_address.go b/common/ip_address.go index e80c446..e88f735 100644 --- a/common/ip_address.go +++ b/common/ip_address.go @@ -30,7 +30,6 @@ func IPFormatToInt(ip string) (int32, uint16) { intIP |= val << (24 - i*8) } - // TODO: Check if this handles negative numbers properly return int32(intIP), uint16(port) } @@ -42,7 +41,6 @@ func IPFormatNoPortToInt(ip string) int32 { func IPFormatToString(ip string) (string, string) { intIP, intPort := IPFormatToInt(ip) - // TODO: Check if this handles negative numbers properly return strconv.FormatInt(int64(intIP), 10), strconv.FormatUint(uint64(intPort), 10) } diff --git a/database/login.go b/database/login.go index d8f9090..bda3b67 100644 --- a/database/login.go +++ b/database/login.go @@ -2,11 +2,14 @@ package database import ( "context" - "database/sql" + "crypto/sha512" + "encoding/hex" + "github.com/jackc/pgx/v4" "github.com/jackc/pgx/v4/pgxpool" "github.com/logrusorgru/aurora/v3" "strconv" "wwfc/common" + "wwfc/gpcm" "wwfc/logging" ) @@ -63,7 +66,7 @@ func GetNASLogin(pool *pgxpool.Pool, ctx context.Context, authToken string) (int var gsbrcd string err := pool.QueryRow(ctx, GetNASUserLogin, authToken).Scan(&userId, &gsbrcd) if err != nil { - if err == sql.ErrNoRows { + if err == pgx.ErrNoRows { return 0, "" } else { panic(err) @@ -88,11 +91,12 @@ func LoginUserToGPCM(pool *pgxpool.Pool, ctx context.Context, authToken string) } uniqueNickname := common.Base32Encode(userId) + gsbrcd + password := sha512.Sum512(append(gpcm.Salt, []byte(gsbrcd)...)) user := User{ UserId: userId, GsbrCode: gsbrcd, - Password: "troll", + Password: hex.EncodeToString(password[:]), Email: uniqueNickname + "@nds", UniqueNick: uniqueNickname, } diff --git a/gpcm/friend.go b/gpcm/friend.go index ce31e9e..05ed444 100644 --- a/gpcm/friend.go +++ b/gpcm/friend.go @@ -101,7 +101,6 @@ func (g *GameSpySession) setStatus(command common.GameSpyCommand) { rawIP |= val << (24 - i*8) } - // TODO: Check if this handles negative numbers correctly ip := strconv.FormatInt(int64(int32(rawIP)), 10) statusMsg := "|s|" + status + "|ss|" + statstring + "|ls|" + locstring + "|ip|" + ip + "|p|0|qm|0" @@ -205,7 +204,6 @@ func (g *GameSpySession) sendLogoutStatus() { rawIP |= val << (24 - i*8) } - // TODO: Check if this handles negative numbers correctly ip := strconv.FormatInt(int64(int32(rawIP)), 10) mutex.Lock() diff --git a/gpcm/main.go b/gpcm/main.go index cf2bd41..2f4e567 100644 --- a/gpcm/main.go +++ b/gpcm/main.go @@ -9,6 +9,7 @@ import ( "github.com/logrusorgru/aurora/v3" "io" "net" + "os" "sync" "wwfc/common" "wwfc/database" @@ -29,6 +30,7 @@ type GameSpySession struct { var ( ctx = context.Background() pool *pgxpool.Pool + Salt []byte // I would use a sync.Map instead of the map mutex combo, but this performs better. sessions = map[uint32]*GameSpySession{} mutex = sync.RWMutex{} @@ -50,6 +52,11 @@ func StartServer() { panic(err) } + Salt, err = os.ReadFile("salt.bin") + if err != nil { + panic(err) + } + address := config.Address + ":29900" l, err := net.Listen("tcp", address) if err != nil { diff --git a/schema.sql b/schema.sql new file mode 100644 index 0000000..6b3c5a1 --- /dev/null +++ b/schema.sql @@ -0,0 +1,200 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 14.9 (Ubuntu 14.9-0ubuntu0.22.04.1) +-- Dumped by pg_dump version 14.9 (Homebrew) + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: logins; Type: TABLE; Schema: public; Owner: wiilink +-- + +CREATE TABLE public.logins ( + id integer NOT NULL, + auth_token character varying NOT NULL, + user_id bigint NOT NULL, + gsbrcd character varying +); + + +ALTER TABLE public.logins OWNER TO wiilink; + +-- +-- Name: logins_id_seq; Type: SEQUENCE; Schema: public; Owner: wiilink +-- + +CREATE SEQUENCE public.logins_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.logins_id_seq OWNER TO wiilink; + +-- +-- Name: logins_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: wiilink +-- + +ALTER SEQUENCE public.logins_id_seq OWNED BY public.logins.id; + + +-- +-- Name: sessions; Type: TABLE; Schema: public; Owner: wiilink +-- + +CREATE TABLE public.sessions ( + id integer NOT NULL, + session_key character varying NOT NULL, + profile_id integer NOT NULL, + login_ticket character varying NOT NULL +); + + +ALTER TABLE public.sessions OWNER TO wiilink; + +-- +-- Name: sessions_id_seq; Type: SEQUENCE; Schema: public; Owner: wiilink +-- + +CREATE SEQUENCE public.sessions_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.sessions_id_seq OWNER TO wiilink; + +-- +-- Name: sessions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: wiilink +-- + +ALTER SEQUENCE public.sessions_id_seq OWNED BY public.sessions.id; + + +-- +-- Name: users; Type: TABLE; Schema: public; Owner: wiilink +-- + +CREATE TABLE public.users ( + profile_id integer NOT NULL, + user_id bigint NOT NULL, + gsbrcd character varying NOT NULL, + password character varying NOT NULL, + email character varying NOT NULL, + unique_nick character varying NOT NULL, + firstname character varying, + lastname character varying DEFAULT ''::character varying, + mariokartwii_friend_info character varying +); + + +ALTER TABLE public.users OWNER TO wiilink; + +-- +-- Name: users_profile_id_seq; Type: SEQUENCE; Schema: public; Owner: wiilink +-- + +CREATE SEQUENCE public.users_profile_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.users_profile_id_seq OWNER TO wiilink; + +-- +-- Name: users_profile_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: wiilink +-- + +ALTER SEQUENCE public.users_profile_id_seq OWNED BY public.users.profile_id; + + +-- +-- Name: logins id; Type: DEFAULT; Schema: public; Owner: wiilink +-- + +ALTER TABLE ONLY public.logins ALTER COLUMN id SET DEFAULT nextval('public.logins_id_seq'::regclass); + + +-- +-- Name: sessions id; Type: DEFAULT; Schema: public; Owner: wiilink +-- + +ALTER TABLE ONLY public.sessions ALTER COLUMN id SET DEFAULT nextval('public.sessions_id_seq'::regclass); + + +-- +-- Name: users profile_id; Type: DEFAULT; Schema: public; Owner: wiilink +-- + +ALTER TABLE ONLY public.users ALTER COLUMN profile_id SET DEFAULT nextval('public.users_profile_id_seq'::regclass); + + +-- +-- Name: logins logins_auth_token_key; Type: CONSTRAINT; Schema: public; Owner: wiilink +-- + +ALTER TABLE ONLY public.logins + ADD CONSTRAINT logins_auth_token_key UNIQUE (auth_token); + + +-- +-- Name: logins logins_pkey; Type: CONSTRAINT; Schema: public; Owner: wiilink +-- + +ALTER TABLE ONLY public.logins + ADD CONSTRAINT logins_pkey PRIMARY KEY (id); + + +-- +-- Name: logins logins_user_id_key; Type: CONSTRAINT; Schema: public; Owner: wiilink +-- + +ALTER TABLE ONLY public.logins + ADD CONSTRAINT logins_user_id_key UNIQUE (user_id, gsbrcd); + + +-- +-- Name: sessions sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: wiilink +-- + +ALTER TABLE ONLY public.sessions + ADD CONSTRAINT sessions_pkey PRIMARY KEY (id); + + +-- +-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: wiilink +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_pkey PRIMARY KEY (profile_id); + + +-- +-- PostgreSQL database dump complete +-- +