git-svn-id: svn://losandesgames.com/alfheim-website@28 15359d88-9307-4e75-a9c1-e5686e5897df

This commit is contained in:
Vicente Ferrari Smith 2024-05-27 01:41:33 +00:00
parent 8c841e1846
commit 13a0a5370e
14 changed files with 94 additions and 87 deletions

View File

@ -11,9 +11,9 @@ build:
.PHONY: deploy .PHONY: deploy
deploy: deploy:
rsync -rP --delete bin/linux_amd64 alfheim@alfheimgame.com:~ rsync -rP --delete bin/linux_amd64 alfheim@alfheimgame.com:/home/alfheim
.PHONY: service .PHONY: service
service: service:
rsync -P alfheimgame.service alfheim@alfheimgame.com:~ rsync -P alfheimgame.service alfheim@alfheimgame.com:/home/alfheim
ssh -t alfheim@alfheimgame.com 'sudo mv ~/alfheimgame.service /etc/systemd/system && sudo systemctl enable alfheimgame && sudo systemctl restart alfheimgame' ssh -t alfheim@alfheimgame.com 'sudo mv /home/alfheim/alfheimgame.service /etc/systemd/system && sudo systemctl enable alfheimgame && sudo systemctl restart alfheimgame'

View File

@ -15,7 +15,7 @@ CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_BIND_SERVICE
EnvironmentFile=/etc/environment EnvironmentFile=/etc/environment
WorkingDirectory=/home/alfheim/linux_amd64 WorkingDirectory=/home/alfheim/linux_amd64
ExecStart=/home/alfheim/linux_amd64/alfheimgame -addr ':8080' ExecStart=/home/alfheim/linux_amd64/alfheimgame -production
Restart=on-failure Restart=on-failure
RestartSec=5 RestartSec=5

Binary file not shown.

Binary file not shown.

View File

@ -48,7 +48,7 @@
</main> </main>
<footer> <footer>
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Studios, Vienna, Austria. All rights reserved. Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Games, Vienna, Austria. All rights reserved.
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -1,9 +1,9 @@
{{define "body"}} {{define "body"}}
<p>Alfheim is a game about humanity: our own will, and our place in the world at large.</p> <p>Alfheim is a game about humanity: our own will, and our place in the world at large.</p>
<p>Alfheim is an MMO where you&mdash;the player&mdash;administers a medieval settlement of elves. <p>Alfheim is an MMO where you&mdash;the player&mdash;administer a medieval settlement of elves.
In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p> In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p>
<br \> <br \>
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video> <video playsinline loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<br \> <br \>
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain"> <img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
{{end}} {{end}}

View File

@ -48,7 +48,7 @@
</main> </main>
<footer> <footer>
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Studios, Vienna, Austria. All rights reserved. Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Games, Vienna, Austria. All rights reserved.
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -1,9 +1,9 @@
{{define "body"}} {{define "body"}}
<p>Alfheim is a game about humanity: our own will, and our place in the world at large.</p> <p>Alfheim is a game about humanity: our own will, and our place in the world at large.</p>
<p>Alfheim is an MMO where you&mdash;the player&mdash;administers a medieval settlement of elves. <p>Alfheim is an MMO where you&mdash;the player&mdash;administer a medieval settlement of elves.
In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p> In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p>
<br \> <br \>
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video> <video playsinline loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<br \> <br \>
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain"> <img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
{{end}} {{end}}

View File

@ -8,7 +8,6 @@ import "fmt"
import "log" import "log"
import "net/http" import "net/http"
import "html/template" import "html/template"
import "os"
import "encoding/json" import "encoding/json"
//import "strconv" //import "strconv"
import "strings" import "strings"
@ -40,7 +39,7 @@ func favicon(w http.ResponseWriter, r *http.Request) {
func authenticated_user(w http.ResponseWriter, r *http.Request) int32 { func authenticated_user(w http.ResponseWriter, r *http.Request) int32 {
session, err := store.Get(r, "id") session, err := store.Get(r, "id")
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
return 0 return 0
} }
@ -161,7 +160,7 @@ func login(w http.ResponseWriter, r *http.Request) {
if id > 0 { if id > 0 {
session.Values["id"] = id session.Values["id"] = id
//fmt.Println("Logged in with id:", id) //log.Println("Logged in with id:", id)
session.Save(r, w) session.Save(r, w)
http.Redirect(w, r, "/account", http.StatusSeeOther) http.Redirect(w, r, "/account", http.StatusSeeOther)
} }
@ -268,7 +267,7 @@ func account(w http.ResponseWriter, r *http.Request) {
id := authenticated_user(w, r) id := authenticated_user(w, r)
account, err := users.GetAccount(id) account, err := users.GetAccount(id)
//fmt.Println(id, account) //log.Println(id, account)
text, err := template.ParseFiles("ui/base.html", "ui/account.html") text, err := template.ParseFiles("ui/base.html", "ui/account.html")
if err != nil { if err != nil {
@ -299,7 +298,7 @@ func deleteaccount(w http.ResponseWriter, r *http.Request) {
switch r.Method { switch r.Method {
case http.MethodPost: case http.MethodPost:
fmt.Println("Deleting account with id ", id) log.Println("Deleting account with id ", id)
users.Delete(id) users.Delete(id)
session, _ := store.Get(r, "id") session, _ := store.Get(r, "id")
@ -323,7 +322,7 @@ func subscribe(w http.ResponseWriter, r *http.Request) {
prices := make([]stripe.Price, 0) prices := make([]stripe.Price, 0)
for results.Next() { for results.Next() {
//fmt.Println(results.Current()) //log.Println(results.Current())
prices = append(prices, *results.Price()) prices = append(prices, *results.Price())
} }
@ -361,7 +360,7 @@ func subscribe_stripe(w http.ResponseWriter, r *http.Request) {
} }
result, err := customersession.New(params) result, err := customersession.New(params)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
} }
text, err := template.ParseFiles("ui/base.html", "ui/subscribe_stripe.html") text, err := template.ParseFiles("ui/base.html", "ui/subscribe_stripe.html")
@ -381,7 +380,7 @@ func managebilling(w http.ResponseWriter, r *http.Request) {
id := authenticated_user(w, r) id := authenticated_user(w, r)
account, err := users.GetAccount(id) account, err := users.GetAccount(id)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
} }
params := &stripe.BillingPortalSessionParams{ params := &stripe.BillingPortalSessionParams{
@ -391,7 +390,7 @@ func managebilling(w http.ResponseWriter, r *http.Request) {
result, err := session.New(params) result, err := session.New(params)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
} }
http.Redirect(w, r, result.URL, http.StatusSeeOther) http.Redirect(w, r, result.URL, http.StatusSeeOther)
@ -402,7 +401,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, MaxBodyBytes) r.Body = http.MaxBytesReader(w, r.Body, MaxBodyBytes)
payload, err := ioutil.ReadAll(r.Body) payload, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err) log.Printf("Error reading request body: %v\n", err)
w.WriteHeader(http.StatusServiceUnavailable) w.WriteHeader(http.StatusServiceUnavailable)
return return
} }
@ -412,14 +411,14 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
event, err := webhook.ConstructEvent(payload, r.Header.Get("Stripe-Signature"), endpointsecret) event, err := webhook.ConstructEvent(payload, r.Header.Get("Stripe-Signature"), endpointsecret)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error verifying webhook signature: %v\n", err) log.Printf("Error verifying webhook signature: %v\n", err)
w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature
return return
} }
err = json.Unmarshal(payload, &event) err = json.Unmarshal(payload, &event)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse webhook body json: %v\n", err.Error()) log.Printf("Failed to parse webhook body json: %v\n", err.Error())
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -430,7 +429,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
var checkoutSession stripe.CheckoutSession var checkoutSession stripe.CheckoutSession
err := json.Unmarshal(event.Data.Raw, &checkoutSession) err := json.Unmarshal(event.Data.Raw, &checkoutSession)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) log.Printf("Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -442,7 +441,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
var paymentIntent stripe.PaymentIntent var paymentIntent stripe.PaymentIntent
err := json.Unmarshal(event.Data.Raw, &paymentIntent) err := json.Unmarshal(event.Data.Raw, &paymentIntent)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) log.Printf("Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -453,7 +452,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
var paymentMethod stripe.PaymentMethod var paymentMethod stripe.PaymentMethod
err := json.Unmarshal(event.Data.Raw, &paymentMethod) err := json.Unmarshal(event.Data.Raw, &paymentMethod)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) log.Printf("Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -462,7 +461,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
var setupIntent stripe.SetupIntent var setupIntent stripe.SetupIntent
err := json.Unmarshal(event.Data.Raw, &setupIntent) err := json.Unmarshal(event.Data.Raw, &setupIntent)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) log.Printf("Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -470,7 +469,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
// ... handle other event types // ... handle other event types
default: default:
fmt.Fprintf(os.Stderr, "Unhandled event type: %s\n", event.Type) log.Printf("Unhandled event type: %s\n", event.Type)
} }
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
@ -478,15 +477,15 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
func handle_checkout_session_completed(checkoutsession stripe.CheckoutSession) error { func handle_checkout_session_completed(checkoutsession stripe.CheckoutSession) error {
//toprint, _ := json.MarshalIndent(checkoutSession, "", " ") //toprint, _ := json.MarshalIndent(checkoutSession, "", " ")
//fmt.Println(string(toprint)) //log.Println(string(toprint))
subscription, err := subscription.Get(checkoutsession.Subscription.ID, nil); subscription, err := subscription.Get(checkoutsession.Subscription.ID, nil);
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
return err return err
} }
//fmt.Println(subscription.Customer.ID) //log.Println(subscription.Customer.ID)
//var status SubscriptionStatus //var status SubscriptionStatus
//switch subscription.Status { //switch subscription.Status {
@ -515,15 +514,15 @@ func handle_checkout_session_completed(checkoutsession stripe.CheckoutSession) e
func handle_payment_method_attached(paymentmethod stripe.PaymentMethod) error { func handle_payment_method_attached(paymentmethod stripe.PaymentMethod) error {
//toprint, _ := json.MarshalIndent(setupintent, "", " ") //toprint, _ := json.MarshalIndent(setupintent, "", " ")
//fmt.Println(string(toprint)) //log.Println(string(toprint))
// make this the new customer's default payment method // make this the new customer's default payment method
params := &stripe.CustomerParams{} params := &stripe.CustomerParams{}
params.DefaultSource = &paymentmethod.ID params.DefaultSource = &paymentmethod.ID
/*result*/_, err := customer.Update(paymentmethod.Customer.ID, params) /*result*/_, err := customer.Update(paymentmethod.Customer.ID, params)
//fmt.Println(result) //log.Println(result)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
return err return err
} }

29
main.go
View File

@ -4,7 +4,6 @@
package main package main
import "fmt"
import "log" import "log"
import "flag" import "flag"
import "net/http" import "net/http"
@ -12,8 +11,6 @@ import _ "github.com/lib/pq"
import "database/sql" import "database/sql"
import "github.com/gorilla/sessions" import "github.com/gorilla/sessions"
import "regexp" import "regexp"
import "golang.org/x/crypto/acme/autocert"
import "crypto/tls"
import "github.com/stripe/stripe-go/v78" import "github.com/stripe/stripe-go/v78"
@ -26,10 +23,13 @@ var store = sessions.NewCookieStore(key)
var emailrx = regexp.MustCompile("/^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/") var emailrx = regexp.MustCompile("/^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/")
func main() { func main() {
addr := flag.String("addr", ":80", "HTTP network addr") addr := flag.String("addr", "127.0.0.1:8080", "HTTP network addr")
prodaddr := flag.String("prodaddr", "45.76.84.7:443", "HTTP network addr")
production := flag.Bool("production", false, "Whether to use production port and TLS")
_ = addr _ = addr
flag.Parse() flag.Parse()
fmt.Println("Hello, Sailor!") log.Println("Hello, Sailor!")
stripe.Key = "sk_test_51PGebgKUHKCjyTmc97rfDPcvew6EhqDz2qp3U7XoAMIilAU9IVo2NO4P7ylkTvbBafFVr94trha1VYY32jRWMw2K00Yq7YJXFf" stripe.Key = "sk_test_51PGebgKUHKCjyTmc97rfDPcvew6EhqDz2qp3U7XoAMIilAU9IVo2NO4P7ylkTvbBafFVr94trha1VYY32jRWMw2K00Yq7YJXFf"
@ -67,7 +67,7 @@ func main() {
//} //}
//for _, acc := range accounts { //for _, acc := range accounts {
// fmt.Println(acc) // log.Println(acc)
//} //}
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
@ -84,19 +84,16 @@ func main() {
//mux.HandleFunc("/managebilling", require_authenticated_user(managebilling)) //mux.HandleFunc("/managebilling", require_authenticated_user(managebilling))
//mux.HandleFunc("/webhook", webhooks) //mux.HandleFunc("/webhook", webhooks)
cert := &autocert.Manager{ if *production {
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("alfheimgame.com", "www.alfheimgame.com"),
Cache: autocert.DirCache("certs"),
}
server := &http.Server{ server := &http.Server{
Addr: ":443", Addr: *prodaddr,
Handler: secure_headers(mux), Handler: log_connection(secure_headers(mux)),
TLSConfig: &tls.Config{GetCertificate: cert.GetCertificate},
} }
go http.ListenAndServe(":http", cert.HTTPHandler(nil))
log.Fatal(server.ListenAndServeTLS("", "")) log.Fatal(server.ListenAndServeTLS("/home/alfheim/cert/config/live/alfheimgame.com/fullchain.pem", "/home/alfheim/cert/config/live/alfheimgame.com/privkey.pem"))
} else {
log.Fatal(http.ListenAndServe(*addr, log_connection(secure_headers(mux))))
}
} }

View File

@ -1,28 +1,39 @@
package main; package main
import "net/http"; import "net/http"
import "log"
func secure_headers(next http.Handler) http.Handler { func secure_headers(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) { fn := func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-XSS-Protection", "1; mode=block"); w.Header().Set("X-XSS-Protection", "1; mode=block")
w.Header().Set("X-Frame-Options", "deny"); w.Header().Set("X-Frame-Options", "deny")
next.ServeHTTP(w, r); next.ServeHTTP(w, r)
} }
return http.HandlerFunc(fn); return http.HandlerFunc(fn)
}
func log_connection(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
log.Println("Connection!")
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
} }
func require_authenticated_user(next http.HandlerFunc) http.HandlerFunc { func require_authenticated_user(next http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// If the user is not authenticated, redirect them to the login page and; // If the user is not authenticated, redirect them to the login page and
// return from the middleware chain so that no subsequent handlers in; // return from the middleware chain so that no subsequent handlers in
// the chain are executed.; // the chain are executed.
if authenticated_user(w, r) == 0 { if authenticated_user(w, r) == 0 {
http.Redirect(w, r, "/login", http.StatusSeeOther); http.Redirect(w, r, "/login", http.StatusSeeOther)
return; return
} }
// Otherwise call the next handler in the chain.; // Otherwise call the next handler in the chain.
next.ServeHTTP(w, r); next.ServeHTTP(w, r)
}); })
} }

View File

@ -4,12 +4,13 @@
package main package main
import "fmt"
import "errors" import "errors"
import "time" import "time"
//import "golang.org/x/crypto/bcrypt" //import "golang.org/x/crypto/bcrypt"
import "database/sql" import "database/sql"
import _ "github.com/lib/pq" import _ "github.com/lib/pq"
import "fmt" import "log"
import "github.com/alexedwards/argon2id" import "github.com/alexedwards/argon2id"
import "github.com/stripe/stripe-go/v78" import "github.com/stripe/stripe-go/v78"
@ -66,20 +67,20 @@ func (m *Usermodel) Insert(username string, password string, firstname string, l
//hashedpassword, err := bcrypt.GenerateFromPassword([]byte(password), 12) //hashedpassword, err := bcrypt.GenerateFromPassword([]byte(password), 12)
hashedpassword, err := argon2id.CreateHash(password, argon2id.DefaultParams) hashedpassword, err := argon2id.CreateHash(password, argon2id.DefaultParams)
//fmt.Println(hashedpassword) //log.Println(hashedpassword)
stmt := `INSERT INTO accounts (username, password, firstname, lastname, email, created) VALUES ($1, $2, $3, $4, $5, NOW()) RETURNING id` stmt := `INSERT INTO accounts (username, password, firstname, lastname, email, created) VALUES ($1, $2, $3, $4, $5, NOW()) RETURNING id`
var insertid int32 var insertid int32
row := m.DB.QueryRow(stmt, username, string(hashedpassword), firstname, lastname, email) row := m.DB.QueryRow(stmt, username, string(hashedpassword), firstname, lastname, email)
if row.Err() != nil { if row.Err() != nil {
fmt.Println(row.Err()) log.Println(row.Err())
return 0, row.Err() return 0, row.Err()
} }
err = row.Scan(&insertid) err = row.Scan(&insertid)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
return 0, err return 0, err
} }
@ -91,11 +92,11 @@ func (m *Usermodel) Insert(username string, password string, firstname string, l
stmt = `UPDATE accounts SET stripe_id = $1 WHERE id = $2` stmt = `UPDATE accounts SET stripe_id = $1 WHERE id = $2`
//fmt.Println(customer.ID, insertid) //log.Println(customer.ID, insertid)
_, err = m.DB.Exec(stmt, customer.ID, insertid) _, err = m.DB.Exec(stmt, customer.ID, insertid)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
return 0, err return 0, err
} }
@ -108,16 +109,16 @@ func (m *Usermodel) Delete(id int32) error {
if account.StripeID != "" { if account.StripeID != "" {
/*result*/_, err := customer.Del(account.StripeID, nil) /*result*/_, err := customer.Del(account.StripeID, nil)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
} }
//fmt.Println(result) //log.Println(result)
} }
stmt := `DELETE FROM accounts WHERE id = $1` stmt := `DELETE FROM accounts WHERE id = $1`
_, err = m.DB.Exec(stmt, id) _, err = m.DB.Exec(stmt, id)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
} }
@ -167,11 +168,11 @@ func (m *Usermodel) ExistsAccount(id int32) bool {
stmt := `SELECT EXISTS(SELECT 1 FROM accounts WHERE id = $1)` stmt := `SELECT EXISTS(SELECT 1 FROM accounts WHERE id = $1)`
row := m.DB.QueryRow(stmt, id) row := m.DB.QueryRow(stmt, id)
if row.Err() != nil { if row.Err() != nil {
fmt.Println(row.Err()) log.Println(row.Err())
} }
row.Scan(&exists) row.Scan(&exists)
//fmt.Println(exists) //log.Println(exists)
return exists return exists
} }
@ -182,13 +183,13 @@ func (m *SubscriptionModel) Insert(stripeid string, stripesubscriptionid string,
row := m.DB.QueryRow(stmt, stripeid) row := m.DB.QueryRow(stmt, stripeid)
if row.Err() != nil { if row.Err() != nil {
fmt.Println(row.Err()) log.Println(row.Err())
return 0, row.Err() return 0, row.Err()
} }
err := row.Scan(&id) err := row.Scan(&id)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
return 0, err return 0, err
} }
@ -198,13 +199,13 @@ func (m *SubscriptionModel) Insert(stripeid string, stripesubscriptionid string,
row = m.DB.QueryRow(stmt, id, string(stripesubscriptionid), string(stripecheckoutid), string(status)) row = m.DB.QueryRow(stmt, id, string(stripesubscriptionid), string(stripecheckoutid), string(status))
if row.Err() != nil { if row.Err() != nil {
fmt.Println(row.Err()) log.Println(row.Err())
return 0, row.Err() return 0, row.Err()
} }
err = row.Scan(&insertid) err = row.Scan(&insertid)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
return 0, err return 0, err
} }
@ -216,7 +217,7 @@ func (m *SubscriptionModel) Delete(id int32) error {
_, err := m.DB.Exec(stmt, id) _, err := m.DB.Exec(stmt, id)
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
return err return err
} }
@ -240,7 +241,7 @@ func (m *SubscriptionModel) GetSubscription(id int32) (Subscription, error) {
return Subscription{}, err return Subscription{}, err
} }
//fmt.Println(subscription.Status) //log.Println(subscription.Status)
return subscription, nil return subscription, nil
} }
@ -276,7 +277,6 @@ func (m *SubscriptionModel) GetSubscriptionsFromAccount(accountid int32) ([]Subs
func (m *SubscriptionModel) HasActiveSubscription(accountid int32) bool { func (m *SubscriptionModel) HasActiveSubscription(accountid int32) bool {
subscriptions, err := m.GetSubscriptionsFromAccount(accountid) subscriptions, err := m.GetSubscriptionsFromAccount(accountid)
if err != nil { if err != nil {
fmt.Println(err)
return false return false
} }

View File

@ -48,7 +48,7 @@
</main> </main>
<footer> <footer>
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Studios, Vienna, Austria. All rights reserved. Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Games, Vienna, Austria. All rights reserved.
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -3,7 +3,7 @@
<p>Alfheim is an MMO where you&mdash;the player&mdash;administer a medieval settlement of elves. <p>Alfheim is an MMO where you&mdash;the player&mdash;administer a medieval settlement of elves.
In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p> In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p>
<br \> <br \>
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video> <video playsinline loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<br \> <br \>
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain"> <img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
{{end}} {{end}}