-
-
Notifications
You must be signed in to change notification settings - Fork 22
SQL Features
Gopher's SQL features will enable you to use all the database
package's functionalities:
- Account creation
- Logging users in with their account name, password, and any custom checks
- Auto-login with generated secure keys
- Custom account information
- Friending
If you do not wish to use the SQL features, you will need to implement your own mechanisms for the features listed above.
Before you can use the SQL features, you will need a MySQL or similar database installed and running on your system. You can acquire the latest version of MySQL at: www.mysql.com
Once you've installed and ran SQL database, you will need to make a new user that Gopher will use to log into the database with. Make sure the user has the following privileges granted: SELECT
, INSERT
, UPDATE
, DELETE
, EXECUTE
, CREATE
, ALTER
, REFERENCES
, and DROP
. You also will need to know the following information about your database for later: IP address, port number, and network protocol. If you haven't done so already, make a database where Gopher can create it's tables.
Now, with all this information you can set the required entries in gopher.ServerSettings
to enable the SQL features:
package main
import (
"github.com/hewiefreeman/GopherGameServer"
)
func main() {
settings := gopher.ServerSettings{
ServerName: "!s!",
MaxConnections: 10000,
HostName: "http://example.com",
HostAlias: "http://www.example.com",
IP: "192.168.1.1",
Port: 8080,
OriginOnly: true,
// Using a TLS/SSL connection is highly recommended when using SQL features!
TLS: true,
CertFile: "C:/path/to/certificate.pem",
PrivKeyFile: "C:/path/to/privkey.pem",
// Enable SQL features
SqlIP: "localhost",
SqlPort: 3306,
SqlProtocol: "tcp",
SqlUser: "userName",
SqlPassword: "password",
SqlDatabase: "databaseName",
}
//
gopher.Start(&settings)
}
Warning: As stated in the above comment, it is highly recommended to use an encrypted TLS/SSL connection when using the SQL features, or sensitive account information can be compromised with network "snooping" (AKA "sniffing"). If you are not using an encrypted connection and do not know where to start, you can start by acquiring a free SSL certificate from Let's Encrypt and reading through their (or your web/cloud hosting provider's) documentation and help sections.
Gopher server and the client APIs will take care of most of the work from here. With the above entries in ServerSettings
set, Gopher will now use the database to log clients in, enable clients to sign-up, and enable friending. A client will be required to sign-up before logging in unless they log in as a guest. It is highly recommended to not use the users.Login()
function, and now rely on the client API to send built-in commands, and let Gopher take care of the rest.
Check out your client API documentation to learn how to send the built-in (sign up, log in, log out, etc) commands from there.
You can attach custom info to an account with a database.AccountInfoColumn
. An AccountInfoColumn
registers a new column on the database in the table where User
accounts are stored. You can make a new AccountInfoColumn
with the database.NewAccountInfoColumn()
method. This (like most set-up functions) can only be called before starting the server:
func main() {
// Enable required settings
settings := gopher.ServerSettings{
ServerName: "!s!",
// ...
}
// Register the new AccountInfoColumn "email"
emailErr := database.NewAccountInfoColumn("email", database.DataTypeVarChar, 255, 0, true, true, false)
if emailErr != nil {
Println(emailErr)
return
}
//
gopher.Start(&settings)
}
The NewAccountInfoColumn()
method's parameters are shown here as in the documentation:
func NewAccountInfoColumn(name string, dataType int, maxSize int, precision int, notNull bool, unique bool, encrypt bool) error
name
is the name of the new info column, dataType
should be one of the SQL data types defined in the documentation, maxSize
is the maximum size of any data inserted to the column, precision
is the decimal precision for numeric types, notNull
prevents any new entries in that column from being null, unique
makes sure no two of the same values are stored in that column, and encrypt
will encrypt the column data before inserting.
The first time booting after registering a new AccountInfoColumn
, Gopher will add a column of that name, data type, max size, etc to the User
accounts table. With a custom AccountInfoColumn
registered, we can continue on to customize the authentication features.
There are many ways to customize the authentication features, so I think it's most logical to list them in order of relevance:
Using the "email" AccountInfoColumn
we registered before, we can make it required for a client to supply an email as well as an account name and password when signing up by using the 'database.SetCustomSignupRequirements()' method:
func main() {
// Enable required settings
settings := gopher.ServerSettings{
ServerName: "!s!",
// ...
}
// Register the new AccountInfoColumn "email"
database.NewAccountInfoColumn("email", database.DataTypeVarChar, 255, 0, true, true, false)
// Require the "email" AccountInfoColumn when signing up
custSignupErr := database.SetCustomSignupRequirements([]string{"email"})
if custSignupErr != nil {
Println(custSignupErr)
return
}
//
gopher.Start(&settings)
}
Note: You can assign multiple custom
AccountInfoColumn
s to be requirements by adding their names to the[]string
passed toSetCustomSignupRequirements()
, or any other custom requirements setter method.
Now, we can capture the input from the client API by setting the sign up callback with the gopher.SetSignupCallback()
method and, for instance, send an email to the provided address:
func main() {
// Enable required settings
settings := gopher.ServerSettings{
ServerName: "!s!",
// ...
}
// Register the new AccountInfoColumn "email"
database.NewAccountInfoColumn("email", database.DataTypeVarChar, 255, 0, true, true, false)
// Require the "email" AccountInfoColumn when signing up
database.SetCustomSignupRequirements([]string{"email"})
// Set sign up callback
cbErr := SetSignupCallback(clientSignUp)
if cbErr != nil {
fmt.Println(cbErr)
return
}
//
gopher.Start(&settings)
}
func clientSignUp(userName string, clientColumns map[string]interface{}) bool {
if email, ok = clientColumns["email"].(string); !ok {
// Check if valid address format and send an email...
// You should return false if address is not email format
} else {
// email is not a string
return false
}
// Allow sign up
return true
}
This callback takes two parameters: userName
(string
), and clientColumns
(map[string]interface{}
). userName
is the account/User
name the client wants, and the clientColumns
are the client's input for your defined (and in this case required) AccountInfoColumn
s.
The sign up callback runs before a client can sign up, so you can either have your callback return true
to allow the sign up, or false
to prevent it. This is useful for verifying correct and/or formatted input.
Note: You can still pass
clientColumns
from the client API without usingSetCustomSignupRequirements()
or any other custom database action requirement setters. The difference is that the requirement setters will send an error back to the client if theclientColumns
do not match the required ones. For example, if your custom requirements for changing a password includesecurityAnswer
, theclientColumns
sent from the client API for a password change request must only containsecurityAnswer
. Otherwise, an error will be sent back to the client API, and the sign up will be prevented.
If you notice there is lacking information, missing features, or bad explanations, please open an issue. All requests are acceptable and will be taken into consideration.