diff --git a/server/go.mod b/server/go.mod index 6a796b9b..f8cf90d1 100644 --- a/server/go.mod +++ b/server/go.mod @@ -2,4 +2,7 @@ module github.com/lxgr-linux/pokete/server go 1.20 -require github.com/joho/godotenv v1.5.1 +require ( + github.com/joho/godotenv v1.5.1 + golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 +) diff --git a/server/go.sum b/server/go.sum index d61b19e1..8f0243ff 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,2 +1,4 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= +golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= diff --git a/server/main.go b/server/main.go index 5f01a545..5fd85bab 100644 --- a/server/main.go +++ b/server/main.go @@ -77,13 +77,11 @@ func handleRequests(res []byte, connection *net.Conn) error { } func processClient(connection net.Conn) { - defer connection.Close() for { buffer := make([]byte, 1024) mLen, err := connection.Read(buffer) if err != nil { fmt.Println("Error reading:", err) - user_repository.RemoveByConn(&connection) break } err = handleRequests(buffer[:mLen], &connection) @@ -92,4 +90,6 @@ func processClient(connection net.Conn) { break } } + _ = user_repository.RemoveByConn(&connection) + connection.Close() } diff --git a/server/requests/requests.go b/server/requests/requests.go index 367b2819..3cad8378 100644 --- a/server/requests/requests.go +++ b/server/requests/requests.go @@ -1,8 +1,8 @@ package requests import ( - "fmt" - "github.com/lxgr-linux/pokete/server/config" + "fmt" + "github.com/lxgr-linux/pokete/server/config" "github.com/lxgr-linux/pokete/server/responses" "github.com/lxgr-linux/pokete/server/user_repository" "net" @@ -24,10 +24,33 @@ type Request[T RequestBody] struct { Body T } -type RequestPosition user_repository.Position +type RequestPosition struct { + user_repository.Position +} + +func (r RequestPosition) Handle(connection *net.Conn) error { + users := user_repository.GetAllUsers() + err, thisUser := user_repository.GetByConn(connection); if err != nil { + return err + } + err = user_repository.SetNewPositionToUser(thisUser.Name, r.Position); if err != nil { + err = responses.WritePositionImplausibleResponse(connection, err.Error()); if err != nil { + return err + } + return fmt.Errorf("connection closed") + } + err, thisUser = user_repository.GetByConn(connection); if err != nil { + return err + } + for _, user := range users { + if user.Conn != connection { + err := responses.WritePositionChangeResponse(user.Conn, thisUser) + if err != nil { + return err + } + } + } -func (r RequestPosition) Handle(_ *net.Conn) error { - fmt.Println("Yes") return nil } @@ -50,9 +73,7 @@ func (r RequestHandshake) Handle(connection *net.Conn) error { if err != nil { return err } - (*connection).Close() - - return nil + return fmt.Errorf("connection closed") } err := user_repository.Add(newUser) @@ -62,9 +83,7 @@ func (r RequestHandshake) Handle(connection *net.Conn) error { if err != nil { return err } - (*connection).Close() - - return nil + return fmt.Errorf("connection closed") } for _, user := range users { diff --git a/server/responses/responses.go b/server/responses/responses.go index 5442d64a..3c122a6c 100644 --- a/server/responses/responses.go +++ b/server/responses/responses.go @@ -2,9 +2,9 @@ package responses import ( "encoding/json" - "fmt" - "github.com/lxgr-linux/pokete/server/config" - "github.com/lxgr-linux/pokete/server/map_repository" + "fmt" + "github.com/lxgr-linux/pokete/server/config" + "github.com/lxgr-linux/pokete/server/map_repository" "github.com/lxgr-linux/pokete/server/user_repository" "net" ) @@ -16,6 +16,7 @@ const ( ResponseType_POSITION_CHANGE ResponseType_USER_ALLREADY_PRESENT ResponseType_VERSION_MISMATCH + ResponseType_POSITION_IMPLAUSIBLE ) func writeResponse(connection *net.Conn, response Response) error { @@ -63,12 +64,22 @@ func WriteUserAllreadyTakenResponse(connection *net.Conn) error { ) } +func WritePositionImplausibleResponse(connection *net.Conn, message string) error { + return writeResponse( + connection, + Response{ + Type: ResponseType_POSITION_IMPLAUSIBLE, + Body: message, + }, + ) +} + func WriteVersionMismatchResponse(connection *net.Conn) error { return writeResponse( connection, Response{ Type: ResponseType_VERSION_MISMATCH, - Body: fmt.Sprintf("Required version is %s", config.Get().ClientVersion), + Body: fmt.Sprintf("Required version is %s", config.Get().ClientVersion), }, ) } diff --git a/server/user_repository/user.go b/server/user_repository/user.go index 0ec773f7..1f33305b 100644 --- a/server/user_repository/user.go +++ b/server/user_repository/user.go @@ -1,6 +1,11 @@ package user_repository -import "net" +import ( + "fmt" + "net" + + "golang.org/x/exp/slices" +) type User struct { Name string @@ -12,3 +17,24 @@ type Position struct { X uint64 Y uint32 } + +func (p *Position) Change(newPosition Position) error { + if p.isPlausible(newPosition) { + p.X = newPosition.X + p.Y = newPosition.Y + return nil + } + return fmt.Errorf("position %v is not playsible to result from %v", newPosition, *p) +} + +func (p Position) isPlausible(newPosition Position) bool { + return slices.Contains( + []Position{ + {p.X, p.Y + 1}, + {p.X, p.Y - 1}, + {p.X + 1, p.Y}, + {p.X - 1, p.Y}, + }, + newPosition, + ) +} diff --git a/server/user_repository/user_repository.go b/server/user_repository/user_repository.go index f33be282..16e46063 100644 --- a/server/user_repository/user_repository.go +++ b/server/user_repository/user_repository.go @@ -32,13 +32,21 @@ func Remove(name string) { delete(*users, name) } -func RemoveByConn(conn *net.Conn) { - for name, user := range *users { +func GetByConn(conn *net.Conn) (error, User){ + for _, user := range *users { if user.Conn == conn { - Remove(name) - break + return nil, user } } + return fmt.Errorf("user with given connection was not found, somebody fucked up badly"), User{} +} + +func RemoveByConn(conn *net.Conn) error { + err, user := GetByConn(conn); if err != nil { + return err + } + Remove(user.Name) + return nil } func GetAllUsers() (retUsers []User) { @@ -48,6 +56,13 @@ func GetAllUsers() (retUsers []User) { return } +func SetNewPositionToUser(name string, newPosition Position) error { + user := (*users)[name] + err := user.Position.Change(newPosition) + (*users)[name] = user + return err +} + func GetStartPosition() Position { return Position{ X: 4,