git-svn-id: svn://losandesgames.com/alfheim-website@26 15359d88-9307-4e75-a9c1-e5686e5897df
This commit is contained in:
parent
a716bcfdea
commit
abbcdb2ea6
19
Makefile
Normal file
19
Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
build:
|
||||
@echo "Building the website..."
|
||||
go build -o bin/alfheimgame
|
||||
cp -r ui bin
|
||||
cp -r static bin
|
||||
cp favicon.ico bin
|
||||
GOOS=linux GOARCH=amd64 go build -o bin/linux_amd64/alfheimgame
|
||||
cp -r ui bin/linux_amd64
|
||||
cp -r static bin/linux_amd64
|
||||
cp favicon.ico bin/linux_amd64
|
||||
|
||||
.PHONY: deploy
|
||||
deploy:
|
||||
rsync -rP --delete bin/linux_amd64 alfheim@alfheimgame.com:~
|
||||
|
||||
.PHONY: service
|
||||
service:
|
||||
rsync -P alfheimgame.service alfheim@alfheimgame.com:~
|
||||
ssh -t alfheim@alfheimgame.com 'sudo mv ~/alfheimgame.service /etc/systemd/system && sudo systemctl enable alfheimgame && sudo systemctl restart alfheimgame'
|
||||
24
alfheimgame.service
Normal file
24
alfheimgame.service
Normal file
@ -0,0 +1,24 @@
|
||||
[Unit]
|
||||
Description=alfheimgame.com website service
|
||||
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
StartLimitIntervalSec=600
|
||||
StartLimitBurst=5
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=alfheim
|
||||
Group=alfheim
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
EnvironmentFile=/etc/environment
|
||||
WorkingDirectory=/home/alfheim/linux_amd64
|
||||
ExecStart=/home/alfheim/linux_amd64/alfheimgame -addr ':8080'
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
BIN
bin/alfheimgame
Executable file
BIN
bin/alfheimgame
Executable file
Binary file not shown.
BIN
bin/favicon.ico
Executable file
BIN
bin/favicon.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
BIN
bin/linux_amd64/alfheimgame
Executable file
BIN
bin/linux_amd64/alfheimgame
Executable file
Binary file not shown.
BIN
bin/linux_amd64/favicon.ico
Executable file
BIN
bin/linux_amd64/favicon.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
BIN
bin/linux_amd64/static/Vollkorn-VariableFont_wght.ttf
Normal file
BIN
bin/linux_amd64/static/Vollkorn-VariableFont_wght.ttf
Normal file
Binary file not shown.
BIN
bin/linux_amd64/static/image.png
Normal file
BIN
bin/linux_amd64/static/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M480-120v-80h280v-560H480v-80h280q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H480Zm-80-160-55-58 102-102H120v-80h327L345-622l55-58 200 200-200 200Z"/></svg>
|
||||
|
After Width: | Height: | Size: 279 B |
194
bin/linux_amd64/static/style.css
Normal file
194
bin/linux_amd64/static/style.css
Normal file
@ -0,0 +1,194 @@
|
||||
html {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
/*background: no-repeat url(/static/image.png);
|
||||
background-size: cover;
|
||||
background-position: center;*/
|
||||
background-color: black;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #3475CB;
|
||||
font-family: "Vollkorn";
|
||||
color: white;
|
||||
margin-top: 0px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-bottom: 0px;
|
||||
min-height: 100%;
|
||||
max-width: 900px;
|
||||
}
|
||||
|
||||
header {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 6rem;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
nav {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.navbuttons a {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.maintitle {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.loginbutton {
|
||||
align-self: center;
|
||||
display: flex;
|
||||
background-color: ;
|
||||
padding-top: 15px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 15px;
|
||||
padding-left: 20px;
|
||||
border-radius: 5px;
|
||||
color: black;
|
||||
/*box-shadow: 10px 10px 5px lightblue;*/
|
||||
}
|
||||
|
||||
main {
|
||||
margin: 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
align-content: center;
|
||||
min-height: 100%;
|
||||
max-height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.account-wrapper {
|
||||
background: transparent;
|
||||
border: 2px solid white;
|
||||
backdrop-filter: blur(20px);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 15px;
|
||||
padding: 30px 40px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
background: transparent;
|
||||
border: 2px solid white;
|
||||
backdrop-filter: blur(20px);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 15px;
|
||||
padding: 30px 40px;
|
||||
|
||||
}
|
||||
|
||||
.wrapper h1 {
|
||||
font-size: 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wrapper .input-box {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input-box input {
|
||||
box-sizing: border-box;
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
outline: none;
|
||||
border: 2px solid rgba(255, 255, 255, .2);
|
||||
border-radius: 25px;
|
||||
padding: 10px 45px 10px 20px
|
||||
}
|
||||
|
||||
.input-box input::placeholder {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.wrapper .input-error {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: rgba(240, 0, 0, .8);
|
||||
}
|
||||
|
||||
.input-error input {
|
||||
box-sizing: border-box;
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
outline: none;
|
||||
border: 2px solid rgba(255, 0, 0, .2);
|
||||
border-radius: 25px;
|
||||
padding: 10px 45px 10px 20px
|
||||
}
|
||||
|
||||
.input-error input::placeholder {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.login-btn-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wrapper .btn {
|
||||
width: 100%;
|
||||
outline: none;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.wrapper .register-link {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background-color: #132123;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a:link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wrapper a:link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wrapper a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wrapper a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
BIN
bin/linux_amd64/static/video.mp4
Normal file
BIN
bin/linux_amd64/static/video.mp4
Normal file
Binary file not shown.
22
bin/linux_amd64/ui/account.html
Normal file
22
bin/linux_amd64/ui/account.html
Normal file
@ -0,0 +1,22 @@
|
||||
{{define "body"}}
|
||||
<div class="account-wrapper">
|
||||
<div>Username: {{.Account.Username}}</div>
|
||||
<div>First name: {{.Account.Firstname}}</div>
|
||||
<div>Last name: {{.Account.Lastname}}</div>
|
||||
<div>Color: {{.Account.Color}}</div>
|
||||
</div>
|
||||
|
||||
<div class="wrapper">
|
||||
<form action="/deleteaccount" method="post">
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Delete Account" class="btn">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form method="POST" action="/managebilling">
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Manage Billing" class="btn">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
54
bin/linux_amd64/ui/base.html
Normal file
54
bin/linux_amd64/ui/base.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!--
|
||||
/\ | |--- | | |--- || |\ /|
|
||||
/__\ | |-- |---| |-- || | \ / |
|
||||
/ \ |___ | | | |___ || | \/ |
|
||||
-->
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Alfheim</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="description" content="A handcrafted economy and politics MMO." />
|
||||
<meta name="author" content="Vicente Ferrari Smith" />
|
||||
<meta name="keywords" content="Alfheim, indie, video game, mmo, colony, colony simulator, vicente ferrari smith, game, economy, politics, alfheim" />
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Vollkorn";
|
||||
src: url(/static/Vollkorn-VariableFont_wght.ttf);
|
||||
}
|
||||
</style>
|
||||
<link href="/static/style.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<a href="/"><h1 class="maintitle">Alfheim</h1></a>
|
||||
<div class="navbuttons">
|
||||
{{/*{{if not .ActiveSubscription}}
|
||||
<a href="/subscribe"><div class="loginbutton"><strong>Subscribe</strong></div></a>
|
||||
{{end}}
|
||||
|
||||
{{if .AuthenticatedUser}}
|
||||
<a href="/account"><div class="loginbutton"><strong>Account</strong></div></a>
|
||||
<a href="/logout"><div class="loginbutton"><strong>Log out</strong></div></a>
|
||||
{{else}}
|
||||
<a href="/login"><div class="loginbutton"><strong>Log in</strong><img src="/static/login_24dp_FILL0_wght400_GRAD0_opsz24.svg" alt=""/></div></a>
|
||||
<a href="/register"><div class="loginbutton"><strong>Register</strong></div></a>
|
||||
{{end}}
|
||||
*/}}
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{{template "body" .}}
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
Alfheim © 2024, Vicente Ferrari Smith, Los Andes Studios, Vienna, Austria. All rights reserved.
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
9
bin/linux_amd64/ui/index.html
Normal file
9
bin/linux_amd64/ui/index.html
Normal file
@ -0,0 +1,9 @@
|
||||
{{define "body"}}
|
||||
<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—the player—administers 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>
|
||||
<br \>
|
||||
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
|
||||
<br \>
|
||||
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
|
||||
{{end}}
|
||||
39
bin/linux_amd64/ui/login.html
Normal file
39
bin/linux_amd64/ui/login.html
Normal file
@ -0,0 +1,39 @@
|
||||
{{define "body"}}
|
||||
<div class="wrapper">
|
||||
<form method="POST">
|
||||
<h1>Log in</h1>
|
||||
|
||||
{{with .FormErrors.generic}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
{{with .FormErrors.username}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
<div {{if .FormErrors.username}}class="input-error"{{else}}class="input-box"{{end}}>
|
||||
<input type="text" id="username" name="username" placeholder="Username" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
{{with .FormErrors.password}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
<div {{if .FormErrors.password}}class="input-error"{{else}}class="input-box"{{end}}>
|
||||
<input type="password" id="password" name="password" placeholder="Password" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Log in" class="btn">
|
||||
</div>
|
||||
<br />
|
||||
<a href="/forgotten">Have you forgotten your password?</a>
|
||||
|
||||
<div class="register-link">
|
||||
<p>Don't have an account? <a href="/register">Register</a></p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
11
bin/linux_amd64/ui/logout.html
Normal file
11
bin/linux_amd64/ui/logout.html
Normal file
@ -0,0 +1,11 @@
|
||||
{{define "body"}}
|
||||
<div class="wrapper">
|
||||
<form method="POST">
|
||||
<h1>Log out</h1>
|
||||
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Log out" class="btn">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
45
bin/linux_amd64/ui/register.html
Normal file
45
bin/linux_amd64/ui/register.html
Normal file
@ -0,0 +1,45 @@
|
||||
{{define "body"}}
|
||||
<div class="wrapper">
|
||||
<form method="POST">
|
||||
<h1>Register</h1>
|
||||
|
||||
{{with .FormErrors.username}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
<div class="input-box" {{with .FormErrors.username}}class="input-error"{{end}}>
|
||||
<input type="text" id="username" name="username" placeholder="Username" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
|
||||
<div class="input-box">
|
||||
<input type="email" id="email" name="email" placeholder="Email" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="input-box">
|
||||
<input type="text" id="firstname" name="firstname" placeholder="First Name" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="input-box">
|
||||
<input type="text" id="lastname" name="lastname" placeholder="Last Name" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
{{with .FormErrors.password}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
<div class="input-box" {{with .FormErrors.password}}class="input-error"{{end}}>
|
||||
<input type="password" id="password" name="password" placeholder="Password" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Register" class="btn">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
8
bin/linux_amd64/ui/subscribe.html
Normal file
8
bin/linux_amd64/ui/subscribe.html
Normal file
@ -0,0 +1,8 @@
|
||||
{{define "body"}}
|
||||
{{range .Prices}}
|
||||
<div class="wrapper">
|
||||
{{$price := divide .UnitAmountDecimal 100}}
|
||||
{{.Currency}} {{printf "%.2f" $price}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
5
bin/linux_amd64/ui/subscribe_stripe.html
Normal file
5
bin/linux_amd64/ui/subscribe_stripe.html
Normal file
@ -0,0 +1,5 @@
|
||||
{{define "body"}}
|
||||
<script async src="https://js.stripe.com/v3/pricing-table.js"></script>
|
||||
<stripe-pricing-table pricing-table-id="prctbl_1PIaJpKUHKCjyTmcy1ONKQiT" publishable-key="pk_test_51PGebgKUHKCjyTmcyuhj7C5lfHfKFLCxRJ2opoqxL3mGEHSRaMvOHYKKgX4MdFfESW78dssjyunboUcFhg3LTwmn005PmzVIXw" customer-session-client-secret={{.ClientSecret}}>
|
||||
</stripe-pricing-table>
|
||||
{{end}}
|
||||
BIN
bin/static/Vollkorn-VariableFont_wght.ttf
Normal file
BIN
bin/static/Vollkorn-VariableFont_wght.ttf
Normal file
Binary file not shown.
BIN
bin/static/image.png
Normal file
BIN
bin/static/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
1
bin/static/login_24dp_FILL0_wght400_GRAD0_opsz24.svg
Normal file
1
bin/static/login_24dp_FILL0_wght400_GRAD0_opsz24.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M480-120v-80h280v-560H480v-80h280q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H480Zm-80-160-55-58 102-102H120v-80h327L345-622l55-58 200 200-200 200Z"/></svg>
|
||||
|
After Width: | Height: | Size: 279 B |
194
bin/static/style.css
Normal file
194
bin/static/style.css
Normal file
@ -0,0 +1,194 @@
|
||||
html {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
/*background: no-repeat url(/static/image.png);
|
||||
background-size: cover;
|
||||
background-position: center;*/
|
||||
background-color: black;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #3475CB;
|
||||
font-family: "Vollkorn";
|
||||
color: white;
|
||||
margin-top: 0px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-bottom: 0px;
|
||||
min-height: 100%;
|
||||
max-width: 900px;
|
||||
}
|
||||
|
||||
header {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 6rem;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
nav {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.navbuttons a {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.maintitle {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.loginbutton {
|
||||
align-self: center;
|
||||
display: flex;
|
||||
background-color: ;
|
||||
padding-top: 15px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 15px;
|
||||
padding-left: 20px;
|
||||
border-radius: 5px;
|
||||
color: black;
|
||||
/*box-shadow: 10px 10px 5px lightblue;*/
|
||||
}
|
||||
|
||||
main {
|
||||
margin: 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
align-content: center;
|
||||
min-height: 100%;
|
||||
max-height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.account-wrapper {
|
||||
background: transparent;
|
||||
border: 2px solid white;
|
||||
backdrop-filter: blur(20px);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 15px;
|
||||
padding: 30px 40px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
background: transparent;
|
||||
border: 2px solid white;
|
||||
backdrop-filter: blur(20px);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 15px;
|
||||
padding: 30px 40px;
|
||||
|
||||
}
|
||||
|
||||
.wrapper h1 {
|
||||
font-size: 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wrapper .input-box {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input-box input {
|
||||
box-sizing: border-box;
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
outline: none;
|
||||
border: 2px solid rgba(255, 255, 255, .2);
|
||||
border-radius: 25px;
|
||||
padding: 10px 45px 10px 20px
|
||||
}
|
||||
|
||||
.input-box input::placeholder {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.wrapper .input-error {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: rgba(240, 0, 0, .8);
|
||||
}
|
||||
|
||||
.input-error input {
|
||||
box-sizing: border-box;
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
outline: none;
|
||||
border: 2px solid rgba(255, 0, 0, .2);
|
||||
border-radius: 25px;
|
||||
padding: 10px 45px 10px 20px
|
||||
}
|
||||
|
||||
.input-error input::placeholder {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.login-btn-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wrapper .btn {
|
||||
width: 100%;
|
||||
outline: none;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.wrapper .register-link {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background-color: #132123;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a:link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wrapper a:link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wrapper a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wrapper a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
BIN
bin/static/video.mp4
Normal file
BIN
bin/static/video.mp4
Normal file
Binary file not shown.
22
bin/ui/account.html
Normal file
22
bin/ui/account.html
Normal file
@ -0,0 +1,22 @@
|
||||
{{define "body"}}
|
||||
<div class="account-wrapper">
|
||||
<div>Username: {{.Account.Username}}</div>
|
||||
<div>First name: {{.Account.Firstname}}</div>
|
||||
<div>Last name: {{.Account.Lastname}}</div>
|
||||
<div>Color: {{.Account.Color}}</div>
|
||||
</div>
|
||||
|
||||
<div class="wrapper">
|
||||
<form action="/deleteaccount" method="post">
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Delete Account" class="btn">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form method="POST" action="/managebilling">
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Manage Billing" class="btn">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
54
bin/ui/base.html
Normal file
54
bin/ui/base.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!--
|
||||
/\ | |--- | | |--- || |\ /|
|
||||
/__\ | |-- |---| |-- || | \ / |
|
||||
/ \ |___ | | | |___ || | \/ |
|
||||
-->
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Alfheim</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="description" content="A handcrafted economy and politics MMO." />
|
||||
<meta name="author" content="Vicente Ferrari Smith" />
|
||||
<meta name="keywords" content="Alfheim, indie, video game, mmo, colony, colony simulator, vicente ferrari smith, game, economy, politics, alfheim" />
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Vollkorn";
|
||||
src: url(/static/Vollkorn-VariableFont_wght.ttf);
|
||||
}
|
||||
</style>
|
||||
<link href="/static/style.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<a href="/"><h1 class="maintitle">Alfheim</h1></a>
|
||||
<div class="navbuttons">
|
||||
{{/*{{if not .ActiveSubscription}}
|
||||
<a href="/subscribe"><div class="loginbutton"><strong>Subscribe</strong></div></a>
|
||||
{{end}}
|
||||
|
||||
{{if .AuthenticatedUser}}
|
||||
<a href="/account"><div class="loginbutton"><strong>Account</strong></div></a>
|
||||
<a href="/logout"><div class="loginbutton"><strong>Log out</strong></div></a>
|
||||
{{else}}
|
||||
<a href="/login"><div class="loginbutton"><strong>Log in</strong><img src="/static/login_24dp_FILL0_wght400_GRAD0_opsz24.svg" alt=""/></div></a>
|
||||
<a href="/register"><div class="loginbutton"><strong>Register</strong></div></a>
|
||||
{{end}}
|
||||
*/}}
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{{template "body" .}}
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
Alfheim © 2024, Vicente Ferrari Smith, Los Andes Studios, Vienna, Austria. All rights reserved.
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
9
bin/ui/index.html
Normal file
9
bin/ui/index.html
Normal file
@ -0,0 +1,9 @@
|
||||
{{define "body"}}
|
||||
<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—the player—administers 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>
|
||||
<br \>
|
||||
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
|
||||
<br \>
|
||||
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
|
||||
{{end}}
|
||||
39
bin/ui/login.html
Normal file
39
bin/ui/login.html
Normal file
@ -0,0 +1,39 @@
|
||||
{{define "body"}}
|
||||
<div class="wrapper">
|
||||
<form method="POST">
|
||||
<h1>Log in</h1>
|
||||
|
||||
{{with .FormErrors.generic}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
{{with .FormErrors.username}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
<div {{if .FormErrors.username}}class="input-error"{{else}}class="input-box"{{end}}>
|
||||
<input type="text" id="username" name="username" placeholder="Username" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
{{with .FormErrors.password}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
<div {{if .FormErrors.password}}class="input-error"{{else}}class="input-box"{{end}}>
|
||||
<input type="password" id="password" name="password" placeholder="Password" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Log in" class="btn">
|
||||
</div>
|
||||
<br />
|
||||
<a href="/forgotten">Have you forgotten your password?</a>
|
||||
|
||||
<div class="register-link">
|
||||
<p>Don't have an account? <a href="/register">Register</a></p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
11
bin/ui/logout.html
Normal file
11
bin/ui/logout.html
Normal file
@ -0,0 +1,11 @@
|
||||
{{define "body"}}
|
||||
<div class="wrapper">
|
||||
<form method="POST">
|
||||
<h1>Log out</h1>
|
||||
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Log out" class="btn">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
45
bin/ui/register.html
Normal file
45
bin/ui/register.html
Normal file
@ -0,0 +1,45 @@
|
||||
{{define "body"}}
|
||||
<div class="wrapper">
|
||||
<form method="POST">
|
||||
<h1>Register</h1>
|
||||
|
||||
{{with .FormErrors.username}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
<div class="input-box" {{with .FormErrors.username}}class="input-error"{{end}}>
|
||||
<input type="text" id="username" name="username" placeholder="Username" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
|
||||
<div class="input-box">
|
||||
<input type="email" id="email" name="email" placeholder="Email" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="input-box">
|
||||
<input type="text" id="firstname" name="firstname" placeholder="First Name" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="input-box">
|
||||
<input type="text" id="lastname" name="lastname" placeholder="Last Name" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
{{with .FormErrors.password}}
|
||||
<label class="error">{{.}}</label>
|
||||
{{end}}
|
||||
|
||||
<div class="input-box" {{with .FormErrors.password}}class="input-error"{{end}}>
|
||||
<input type="password" id="password" name="password" placeholder="Password" required>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="login-btn-wrapper">
|
||||
<input type="submit" value="Register" class="btn">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
8
bin/ui/subscribe.html
Normal file
8
bin/ui/subscribe.html
Normal file
@ -0,0 +1,8 @@
|
||||
{{define "body"}}
|
||||
{{range .Prices}}
|
||||
<div class="wrapper">
|
||||
{{$price := divide .UnitAmountDecimal 100}}
|
||||
{{.Currency}} {{printf "%.2f" $price}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
5
bin/ui/subscribe_stripe.html
Normal file
5
bin/ui/subscribe_stripe.html
Normal file
@ -0,0 +1,5 @@
|
||||
{{define "body"}}
|
||||
<script async src="https://js.stripe.com/v3/pricing-table.js"></script>
|
||||
<stripe-pricing-table pricing-table-id="prctbl_1PIaJpKUHKCjyTmcy1ONKQiT" publishable-key="pk_test_51PGebgKUHKCjyTmcyuhj7C5lfHfKFLCxRJ2opoqxL3mGEHSRaMvOHYKKgX4MdFfESW78dssjyunboUcFhg3LTwmn005PmzVIXw" customer-session-client-secret={{.ClientSecret}}>
|
||||
</stripe-pricing-table>
|
||||
{{end}}
|
||||
2
go.mod
2
go.mod
@ -12,5 +12,7 @@ require (
|
||||
|
||||
require (
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
)
|
||||
|
||||
20
main.go
20
main.go
@ -12,10 +12,10 @@ import _ "github.com/lib/pq"
|
||||
import "database/sql"
|
||||
import "github.com/gorilla/sessions"
|
||||
import "regexp"
|
||||
//import "golang.org/x/crypto/bcrypt"
|
||||
import "golang.org/x/crypto/acme/autocert"
|
||||
import "crypto/tls"
|
||||
|
||||
import "github.com/stripe/stripe-go/v78"
|
||||
//import "github.com/stripe/stripe-go/v78/customer"
|
||||
|
||||
var users *Usermodel
|
||||
var subscriptions *SubscriptionModel
|
||||
@ -27,6 +27,7 @@ var emailrx = regexp.MustCompile("/^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-
|
||||
|
||||
func main() {
|
||||
addr := flag.String("addr", ":80", "HTTP network addr")
|
||||
_ = addr
|
||||
flag.Parse()
|
||||
fmt.Println("Hello, Sailor!")
|
||||
|
||||
@ -83,6 +84,19 @@ func main() {
|
||||
//mux.HandleFunc("/managebilling", require_authenticated_user(managebilling))
|
||||
//mux.HandleFunc("/webhook", webhooks)
|
||||
|
||||
cert := &autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist("alfheimgame.com", "www.alfheimgame.com"),
|
||||
Cache: autocert.DirCache("certs"),
|
||||
}
|
||||
|
||||
log.Fatal(http.ListenAndServe(*addr, secure_headers(mux)))
|
||||
server := &http.Server{
|
||||
Addr: ":443",
|
||||
Handler: secure_headers(mux),
|
||||
TLSConfig: &tls.Config{GetCertificate: cert.GetCertificate},
|
||||
}
|
||||
|
||||
go http.ListenAndServe(":http", cert.HTTPHandler(nil))
|
||||
|
||||
log.Fatal(server.ListenAndServeTLS("", ""))
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<p>Alfheim is an MMO where you—the player—administers 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>
|
||||
<br \>
|
||||
<video autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
|
||||
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
|
||||
<br \>
|
||||
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
|
||||
{{end}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user