Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/environment configuration #116

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/secrets.py
/environment.py
/node/live_variables.js
/node/variables.js
/stack/
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ git clone https://github.com/kaansoral/adventureland-appserver appserver
Set up secrets files and remember to change secret keys!

```sh
cp adventureland/useful/template.environment.py adventureland/environment.py
cp adventureland/useful/template.secrets.py adventureland/secrets.py
cp adventureland/useful/template.variables.js adventureland/node/variables.js
cp adventureland/useful/template.live_variables.js adventureland/node/live_variables.js
Expand Down
23 changes: 20 additions & 3 deletions api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from config import *
from functions import *
import environment

def signup_or_login_api(**args):
#time.sleep(10)
Expand Down Expand Up @@ -1492,9 +1493,25 @@ def reload_server_api(**args):

def create_server_api(**args):
self,domain,keyword,port,region,pvp,gameplay,sname=gdmuld(args,"self","domain","keyword","port","region","pvp","gameplay","name")
if keyword!=secrets.SERVER_MASTER: jhtml(self,{"failed":1}); return
actual_ip=ip=request.remote_addr; server_name="XX"
if is_sdk: actual_ip=ip=domain.server_ip

if keyword!=secrets.SERVER_MASTER: jhtml(self,{"failed":1}); return

actual_ip=ip=request.remote_addr; server_name="XX"

if is_sdk:
# in sdk mode, HTTPS_MODE = False

mappingKey = "%s%s"%(region,sname)
ip = "%s"%(environment.CREATE_SERVER_MAPPING.get(mappingKey,ip))

# actual_ip is used by the appserver to send eval requests to the game server
# so if the game server is a local one in docker, it needs to be the internal docker ip
# TODO: if the game server is hosted externally on another server, it needs to be the ip or hostname that you can talk with over the internet, so using request.remote_addr might not work if it needs to use a hostname
actual_ip = request.remote_addr

logging.info("create_server_api: sname: %s region:%s %s %s"%(sname,region,ip,actual_ip))

# TODO: makes an ip like eu1.adventure.land, this is hardcoded and should be changed
if domain.https_mode: ip="%s.%s"%(ip_to_subdomain.get(ip,ip),live_domain)
lat,lon=(request.headers.get("X-Appengine-Citylatlong")or"0,0").split(",")
try: lat,lon=float(lat),float(lon)
Expand Down
26 changes: 8 additions & 18 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def __getattr__(self,*d,**f):
class GG(): pass

import secrets
import environment

from libraries.country_to_latlon import c_to_ll
#from libraries import get_image_size
Expand Down Expand Up @@ -120,25 +121,14 @@ class GG(): pass
"Last Update [April 25th]",
"Cost reduction trial"
]
ip_to_subdomain={ #IMPORTANT: SPECIAL PAGE RULES ARE NEEDED: https://dash.cloudflare.com/b6f5a13bded5fdd273e4a1cd3777162d/adventure.land/page-rules - uss1 / eus1 was best
"35.187.255.184":"asia1",
"35.246.244.105":"eu1",
"35.228.96.241":"eu2",
"35.234.72.136":"eupvp",
"35.184.37.35":"us1",
"34.67.188.57":"us2",
"34.75.5.124":"us3",
"34.67.187.11":"uspvp",
"195.201.181.245":"eud1",
"158.69.23.127":"usd1",
}
ip_to_subdomain=environment.IP_TO_SUBDOMAIN
HTTPS_MODE=True #IMPORTANT: converts server IP's to subdomain urls at create_server_api [17/11/18]
always_amazon_ses=True
SCREENSHOT_MODE=is_sdk and False
game_name="Adventure Land"
appengine_id="twodimensionalgame"
live_domain='adventure.land'
sdk_domain='thegame.com'
game_name=environment.GAME_NAME
appengine_id=environment.APPENGINE_ID
live_domain=environment.DOMAIN_NAME
sdk_domain=environment.DOMAIN_NAME
SDK_UPLOAD_PASSWORD=ELEMENT_PASSWORD=secrets.sdk_password

def init_request(request):
Expand All @@ -161,7 +151,7 @@ def gdi(request=None):

domain.base_url=protocol + "://" + hostname
domain.pref_url=domain.base_url
domain.server_ip="192.168.1.125"
# domain.server_ip="192.168.1.125" # See environment.py
domain.stripe_pkey=stripe_pkey
domain.stripe_enabled=False
domain.https_mode=False
Expand All @@ -180,7 +170,7 @@ def gdi(request=None):
domain.ip_to_subdomain=ip_to_subdomain
domain.https=False
domain.secure_base_url=domain.base_url.replace("http://","https://")
domain.discord_url="https://discord.gg/44yUVeU"
domain.discord_url=secrets.DISCORD["URL"]["WELCOME"]
domain.is_sdk=is_sdk
domain.io_version="4.2.0" #upgraded from 1.4.5 now [18/03/17] upgraded from 1.7.2 now [31/12/17] upgraded from 2.1.0 now [20/06/19] 2.3.0 [28/06/20] 4.0.0 [18/03/21]
domain.cm_version="5.65.1"
Expand Down
4 changes: 1 addition & 3 deletions functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ def characters_to_client(characters_data):
def servers_to_client(domain,servers_data):
servers=[]
for server in servers_data:
servers.append({"name":server.name,"region":server.region,"players":server.info.players,"key":server.k(),"addr":domain.https and server.ip or server.actual_ip,"port":server.port})
servers.append({"name":server.name,"region":server.region,"players":server.info.players,"key":server.k(),"addr":server.ip,"port":server.port})
return servers

def get_characters(user,_async=False):
Expand Down Expand Up @@ -1053,13 +1053,11 @@ def verify_steam_installs():

def server_eval(server,code,data={}):
ip=server.actual_ip
if is_sdk: ip="0.0.0.0"
return json.loads(fetch_url("http://%s:%s"%(ip,server.port),aevent="eval",spass=secrets.ACCESS_MASTER,code=code.replace("+","%2B"),data=json.dumps(data).replace("+","%2B")))

def server_eval_safe(server,code,data={}):
try:
ip=server.actual_ip
if is_sdk: ip="0.0.0.0"
return json.loads(fetch_url("http://%s:%s"%(ip,server.port),aevent="eval",spass=secrets.ACCESS_MASTER,code=code.replace("+","%2B"),data=json.dumps(data).replace("+","%2B")))
except:
log_trace()
Expand Down
2 changes: 1 addition & 1 deletion htmls/base_script.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
var inside="{% if not user %}login{%else%}selection{%endif%}";
var user_id="{{user and user.k() or ''}}",user_auth="{{user and user.info.auths[0] or ''}}";
var base_url="{{domain.base_url}}";
var server_addr="{{server and (domain.https and server.ip or server.actual_ip) or ''}}",server_port="{{server and server.port or ''}}";
var server_addr="{{server and server.ip or ''}}",server_port="{{server and server.port or ''}}";
var server_names={"US":"Americas","EU":"Europas","ASIA":"Eastlands"};
var sound_music='{%if domain.music_on %}1{%endif%}',sound_sfx='{% if domain.sfx_on %}1{%endif%}',xmas_tunes=false,music_level=0.3;
var perfect_pixels='{% if domain.perfect_pixels%}1{%endif%}';
Expand Down
2 changes: 1 addition & 1 deletion htmls/contents/guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<div class="gray mb5"><span style="color: #F4F4F4">&gt;</span> For accessories, reaching a higher level is more challenging, for an +1 accessory, you need 3x +0 accessories of the same kind, and so on.</div>
<div class="gray mb"><span style="color: #F4F4F4">&gt;</span> You can use "Primordial Shard"s increase the chances of success of both upgrades and compounds, the essence of the shard is absorbed inside the item.</div>
<div class="gamebutton gamebutton-large mt15">Communities | Links</div> <div class="mb5"></div>
<div class="gray mb5"><span style="color: #F4F4F4">&gt;</span> <a href="https://discord.gg/44yUVeU" class="eexternal" target="_blank" style="color: #469ECF; text-decoration: none">Discord:</a> Discord is our most active community, ideal for questions of all kinds and to provide feedback, suggest new ideas. The coding channels are also quite useful.</div>
<div class="gray mb5"><span style="color: #F4F4F4">&gt;</span> <a href="{{domain.discord_url}}" class="eexternal" target="_blank" style="color: #469ECF; text-decoration: none">Discord:</a> Discord is our most active community, ideal for questions of all kinds and to provide feedback, suggest new ideas. The coding channels are also quite useful.</div>
<div class="gray mb5"><span style="color: #F4F4F4">&gt;</span> <a href="https://github.com/kaansoral/adventureland/blob/master/runner_functions.js" class="eexternal" target="_blank" style="color: #469ECF; text-decoration: none">Github:</a> Our Official Github houses the "runner_functions.js" - which includes all the base CODE functions</div>
<div class="gray mb5"><span style="color: #F4F4F4">&gt;</span> <a href="https://www.reddit.com/r/adventureland" class="eexternal" target="_blank" style="color: #469ECF; text-decoration: none">Reddit:</a> You can use Reddit to share things, Discord is more practical for asking quick questions</div>
<div class="gray mb5"><span style="color: #F4F4F4">&gt;</span> <a href="https://docs.google.com/document/d/18xG9NaO1mm7cSx7wMIQEtrkGzFHo6WrEE_TZcbeAFnA/edit" class="eexternal" target="_blank" style="color: #469ECF; text-decoration: none">Unofficial Starter Guide</a></div>
Expand Down
2 changes: 1 addition & 1 deletion htmls/contents/section_buttons.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- <a class="gamebutton" href="/logs" target="_blank">Development Diary</a> -->
{% if buttons=="essentials" %}
<a class="gamebutton" href="/docs" style="border-color: #d6d135" target="_blank">Docs</a>
<a class="gamebutton eexternal" href="https://discord.gg/44yUVeU" target="_blank" style="border-color: #32A3B0">Discord!</a>
<a class="gamebutton eexternal" href="{{domain.discord_url}}" target="_blank" style="border-color: #32A3B0">Discord!</a>
{% endif %}
{% if buttons=="musts" %}
{# <div class="gamebutton" onclick="btc(event); show_terms()">Terms</div>
Expand Down
2 changes: 1 addition & 1 deletion htmls/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{% elif content=="contact"%}
You can always email me at [email protected]

Also check out our <a class="eexternal" href="https://discord.gg/44yUVeU" target="_blank" style="border-color: #3386CF">Discord!</a> - You can PM Wizard on Discord for faster and more informal replies :)
Also check out our <a class="eexternal" href="{{domain.discord_url}}" target="_blank" style="border-color: #3386CF">Discord!</a> - You can PM Wizard on Discord for faster and more informal replies :)
{%endif%}
</div>
</td></tr>
Expand Down
13 changes: 6 additions & 7 deletions js/game.js
Original file line number Diff line number Diff line change
Expand Up @@ -1149,16 +1149,15 @@ function init_socket(args)
window.socket.destroy();
}
$(".disconnected").hide();
if(is_sdk && (Cookies.get("windows") || Cookies.get("local_ip") || window.location.host=="advanture.land" || window.location.host=="x.thegame.com")) server_addr="192.168.1.125"; // Cookies.set('windows','1',{expires:12*365});
else if(is_sdk)
{
if(window.location.origin=='http://127.0.0.1/') server_addr="127.0.0.1";
else server_addr="0.0.0.0";

add_log("Connecting to the server.");
if (is_sdk) {
add_log(`${location.protocol} ${server_addr} ${server_port}`);
}

var query=args.secret&&"desktop="+(!is_comm&&1||"")+"&secret="+args.secret||undefined;
if(location.protocol=="https:") window.socket=io('wss://'+server_addr+':'+server_port,{secure:true,transports:['websocket'],query:query});
else window.socket=io(server_addr+':'+server_port,{transports:['websocket'],query:query});
add_log("Connecting to the server.");
else window.socket=io('ws://'+server_addr+':'+server_port,{transports:['websocket'],query:query});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it now explicitely need the protocol but didn't before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be able to connect via caracAL to the server on http, the protocol was required for a correct websocket / socket.io connection to be established.

socket_ready=false; socket_welcomed=false; observing=null; $("#observeui").hide();
original_onevent=socket.onevent;
original_emit=socket.emit;
Expand Down
3 changes: 2 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ def serve_server_and_character_selection(name="",region="",sname=""):
level=c["level"]
for server in servers:
if server.region==region and server.name==sname:
domain.url_ip=domain.https and server.ip or server.actual_ip
# TODO: What is the purpose of this? we also have servers_to_client in functions.py that is used in render_selection and render_comm
domain.url_ip= server.ip
domain.url_port=server.port
logging.info("Set!")
return render_selection(request,user,domain,level=level)
Expand Down
12 changes: 8 additions & 4 deletions node/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ var mode = {
prevent_external: 0, // for "test" / "hardcore"
pvp_level_gap: 0, // have to be within 10 level to attack
};
// Override default settings
mode = { ...mode, ...variables.MODE };
var events = {
// SEASONS
holidayseason: false,
Expand Down Expand Up @@ -9669,10 +9671,12 @@ function init_io() {
// player.vision[1]=min(700,player.vision[1]);
player.vision = B.vision;

if (!player.verified) {
player.s.notverified = { ms: 30 * 60 * 1000 };
} else if (player.s.notverified) {
player.s.notverified = { ms: 100 };
if (mode.notverified_debuff) {
if (!player.verified) {
player.s.notverified = { ms: 30 * 60 * 1000 };
} else if (player.s.notverified) {
player.s.notverified = { ms: 100 };
}
}

if (player.guild) {
Expand Down
17 changes: 12 additions & 5 deletions node/server_functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3270,27 +3270,34 @@ function appengine_call(method, args, on_success, on_error) {
}

function discord_call(message) {
// TODO: should it not post to the channel either way? I vote to remove this return
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd argue that the new variables.DISCORD.ENABLED configuration option has indeed made this check obsolete.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think standard, hardcore and test servers are run from the same directory though. So they all share the same variables.js file.

Should the test server actually post to the same channels as the live servers? The same question is true for hardcore servers.

I kinda feel they perhaps need their own configuration as theese two servers are a special kind of servers.

if (gameplay == "hardcore" || gameplay == "test") {
return;
}

if (is_sdk) {
return server_log("Discord: " + message);
server_log("Discord: " + message);
}
var url = "https://discordapp.com/api/channels/404333059018719233/messages";

if (!variables.DISCORD.ENABLED) {
return;
}

var url = variables.DISCORD.EVENT_CHANNELS.DEFAULT; // #game_events
if (message.search(" joined Adventure Land") != -1) {
url = "https://discordapp.com/api/channels/839163123499794481/messages";
url = variables.DISCORD.EVENT_CHANNELS.NEW_PLAYER; // #new_players
}
request(
{
url: url,
headers: { Authorization: "Bot " + variables.discord_token },
headers: { Authorization: "Bot " + variables.DISCORD.TOKEN },
method: "POST",
json: {
content: message,
},
},
function (err, response, body) {
//console.log(response);
console.log(err, response);
},
);
}
Expand Down
26 changes: 26 additions & 0 deletions useful/template.environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
GAME_NAME = "Adventure Land"
APPENGINE_ID = "twodimensionalgame"
DOMAIN_NAME = "adventure.land"
#IMPORTANT: SPECIAL PAGE RULES ARE NEEDED: https://dash.cloudflare.com/b6f5a13bded5fdd273e4a1cd3777162d/adventure.land/page-rules - uss1 / eus1 was best
IP_TO_SUBDOMAIN = {
thmsndk marked this conversation as resolved.
Show resolved Hide resolved
"35.187.255.184":"asia1",
"35.246.244.105":"eu1",
"35.228.96.241":"eu2",
"35.234.72.136":"eupvp",
"35.184.37.35":"us1",
"34.67.188.57":"us2",
"34.75.5.124":"us3",
"34.67.187.11":"uspvp",
"195.201.181.245":"eud1",
"158.69.23.127":"usd1"
}

# This is responsible for mapping the correct ip/domain that the client should use to connect with in the websocket
CREATE_SERVER_MAPPING = {

# example of how thmsn.adventureland.community works
# "EUI": "eu1.thmsn.adventureland.community"

# When running a local test server on your private machine
"EUI": "localhost"
}
39 changes: 23 additions & 16 deletions useful/template.live_variables.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
module.exports = {
cfunctions_path: "./server/common_functions.js",
functions_path: "./server/server_functions.js",
worker_path: "./server/server_worker.js",
data_path: "./server/data.js",
base_url: "https://yourappspoturldontincludedashes.appspot.com",
keyword: "123",
access_master: "123",
bot_key: "123",
discord_token: "NDXXXXXXXXXXX...",
apple_token: "acXXXXXXXX...",
steam_key: "8aXXXXXXXXX...",
steam_web_key: "B4XXXXXXX...",
steam_partner_key: "F9XXXXXXX...",
close_timeout: 24000,
ip_limit: 3,
character_limit: 3,
cfunctions_path: "./server/common_functions.js",
functions_path: "./server/server_functions.js",
worker_path: "./server/server_worker.js",
data_path: "./server/data.js",
base_url: "https://yourappspoturldontincludedashes.appspot.com",
keyword: "123",
access_master: "123",
bot_key: "123",
apple_token: "acXXXXXXXX...",
steam_key: "8aXXXXXXXXX...",
steam_web_key: "B4XXXXXXX...",
steam_partner_key: "F9XXXXXXX...",
Comment on lines +10 to +13
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, those tokens can probably move to secrets, is there a reason not to?

close_timeout: 24000,
ip_limit: 3,
character_limit: 3,
DISCORD: {
ENABLED: false,
TOKEN: "NDXXXXXXXXXXX",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated token? Why is this here as well? (Maybe you don't even know)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The live variables is used as part of the deploy process on the official servers as far as I understand, there is a script that copies this and some other folders into the deployed directory.

EVENT_CHANNELS: {
DEFAULT: "https://discordapp.com/api/channels/404333059018719233/messages",
NEW_PLAYER: "https://discordapp.com/api/channels/839163123499794481/messages",
},
},
};
7 changes: 7 additions & 0 deletions useful/template.secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@
ssh-keygen -o #Doesn't work
ssh-keygen -t rsa -b 4096
"""

# Discord
DISCORD = {
"URL": {
"WELCOME": "https://discord.gg/44yUVeU"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be named DISCORD_INVITE_LINK instead of WELCOME, for clarity.

Copy link
Contributor Author

@thmsndk thmsndk Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, was just an easy name to represent it as the welcome link i think the welcome name made sense in context of where it was used, I'd have to verify it again though

},
}
49 changes: 31 additions & 18 deletions useful/template.variables.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
const path = require("node:path");

module.exports = {
cfunctions_path: path.resolve(__dirname, "../js/common_functions.js"),
functions_path: path.resolve(__dirname, "server_functions.js"),
worker_path: path.resolve(__dirname, "server_worker.js"),
data_path: path.resolve(__dirname, "data.js"),
base_url: "http://thegame.com",
keyword: "123",
access_master: "123",
bot_key: "123",
discord_token: "NDXXXXXXXXXXX...",
apple_token: "acXXXXXXXX...",
steam_key: "8aXXXXXXXXX...",
steam_web_key: "B4XXXXXXX...",
steam_partner_key: "F9XXXXXXX...",
is_sdk: 1,
close_timeout: 4000,
ip_limit: 3,
character_limit: 3,
fast_sdk: 0,
cfunctions_path: path.resolve(__dirname, "../js/common_functions.js"),
functions_path: path.resolve(__dirname, "server_functions.js"),
worker_path: path.resolve(__dirname, "server_worker.js"),
data_path: path.resolve(__dirname, "data.js"),
base_url: "http://thegame.com",
keyword: "123",
access_master: "123",
bot_key: "123",
apple_token: "acXXXXXXXX...",
steam_key: "8aXXXXXXXXX...",
steam_web_key: "B4XXXXXXX...",
steam_partner_key: "F9XXXXXXX...",
is_sdk: 1,
close_timeout: 4000,
ip_limit: 3,
character_limit: 3,
fast_sdk: 0,
DISCORD: {
ENABLED: false,
TOKEN: "NDXXXXXXXXXXX", // Your discord applications bot token
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this go into secrets instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Secrets is for python.
This is for the node servers

EVENT_CHANNELS: {
DEFAULT: "https://discordapp.com/api/channels/404333059018719233/messages", // #game_events
NEW_PLAYER: "https://discordapp.com/api/channels/839163123499794481/messages", // #new_players
},
},

// mode variable in server.js can be overridden here
MODE: {
drm_check: 0, // Enable steam/mac DRM check, prevents authfail debuff being added if disabled
notverified_debuff: 0, // disables the debuff for not being verified
},
};