diff --git a/client/cmd/main.go b/client/cmd/main.go index ac96e47..c7860d1 100644 --- a/client/cmd/main.go +++ b/client/cmd/main.go @@ -136,11 +136,10 @@ func _main() error { client := proto.NewGameWorldClient(conn) - // TODO registration and login stuff - app := tview.NewApplication() // TODO make a NewClientState + // TODO rename this, like, UI cs := &ClientState{ App: app, SessionInfo: &proto.SessionInfo{}, @@ -256,6 +255,9 @@ func _main() error { cs.SessionInfo = si pages.SwitchToPage("game") + app.SetFocus(commandInput) + // TODO error handle + go cs.Messages() } registerPage.AddButton("gimme that shit", registerSubmitFn) diff --git a/server/cmd/main.go b/server/cmd/main.go index b52a547..7668190 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -144,18 +144,31 @@ func (s *gameWorldServer) Messages(si *proto.SessionInfo, stream proto.GameWorld } func (s *gameWorldServer) Register(ctx context.Context, auth *proto.AuthInfo) (si *proto.SessionInfo, err error) { - var a *db.Account - a, err = s.db.CreateAccount(auth.Username, auth.Password) + var account *db.Account + account, err = s.db.CreateAccount(auth.Username, auth.Password) if err != nil { - return nil, err + return } + var avatar *db.Object + avatar, err = s.db.CreateAvatar(account) + if err != nil { + return + } + + log.Printf("created %#v for %s", avatar, account.Name) + + // TODO create avatar object + // TODO create bedroom object + // TODO put avatar in bedroom + // TODO send room info, avatar info to client (need to figure this out and update proto) + var sessionID string - sessionID, err = s.db.StartSession(*a) + sessionID, err = s.db.StartSession(*account) if err != nil { return nil, err } - log.Printf("started session for %s", a.Name) + log.Printf("started session for %s", account.Name) si = &proto.SessionInfo{SessionID: sessionID} diff --git a/server/db/db.go b/server/db/db.go index f44de6f..5405b8c 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -3,8 +3,11 @@ package db import ( "context" _ "embed" + "encoding/json" "errors" + "fmt" "log" + "math/rand" "github.com/google/uuid" "github.com/jackc/pgx/v4/pgxpool" @@ -22,6 +25,7 @@ type Account struct { type DB interface { // EnsureSchema() TODO look into tern CreateAccount(string, string) (*Account, error) + CreateAvatar(*Account) (*Object, error) ValidateCredentials(string, string) (*Account, error) GetAccount(string) (*Account, error) StartSession(Account) (string, error) @@ -129,3 +133,52 @@ func (db *pgDB) EndSession(sid string) error { return err } + +type Object struct { + ID int + Avatar bool + Bedroom bool + data string +} + +func (db *pgDB) CreateAvatar(account *Account) (avatar *Object, err error) { + // TODO start a transaction + data := map[string]string{} + data["name"] = account.Name + data["description"] = fmt.Sprintf("a gaseous form. it smells faintly of %s.", randSmell()) + d, _ := json.Marshal(data) + avatar = &Object{ + Avatar: true, + data: string(d), + } + + // TODO I need to understand how to make use of INSERT...RETURNING + + // TODO how do I determine what perm id to use? I might want to revisit the + // schema for that so perm knows about an object and not the other way + // around. I could also just store this data on the objects table. I will + // ponder if there is any reasonable argument for a separate permissions + // table. + + _, err = db.pool.Exec(context.Background(), "INSERT ") + if err != nil { + return nil, err + } + + // TODO fetch and return avatar + + return +} + +func randSmell() string { + // TODO seeding + smells := []string{ + "lavender", + "wet soil", + "juniper", + "pine sap", + "wood smoke", + } + ix := rand.Intn(len(smells)) + return smells[ix] +} diff --git a/server/db/schema.sql b/server/db/schema.sql index 2d01b62..0d748ee 100644 --- a/server/db/schema.sql +++ b/server/db/schema.sql @@ -18,12 +18,11 @@ CREATE TABLE permissions ( read perm NOT NULL DEFAULT 'world', write perm NOT NULL DEFAULT 'owner', carry perm NOT NULL DEFAULT 'world', - exec perm NOT NULL DEFAULT 'owner' + exec perm NOT NULL DEFAULT 'world' ); CREATE TABLE objects ( id serial PRIMARY KEY, - shortname varchar(200) NOT NULL UNIQUE, avatar boolean NOT NULL DEFAULT FALSE, bedroom boolean NOT NULL DEFAULT FALSE, data jsonb NOT NULL,