Skip to content

Commit

Permalink
Merge branch 'main' into smw-main
Browse files Browse the repository at this point in the history
  • Loading branch information
PoryGone committed Nov 15, 2022
2 parents aa281ef + 4d79920 commit dcf4108
Show file tree
Hide file tree
Showing 61 changed files with 581 additions and 304 deletions.
28 changes: 6 additions & 22 deletions PokemonClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import bsdiff4
import subprocess
import zipfile
import hashlib
from asyncio import StreamReader, StreamWriter
from typing import List

Expand Down Expand Up @@ -246,31 +245,16 @@ async def patch_and_run_game(game_version, patch_file, ctx):
comp_path = base_name + '.gb'
with open(Utils.local_path(Utils.get_options()["pokemon_rb_options"][f"{game_version}_rom_file"]), "rb") as stream:
base_rom = bytes(stream.read())
try:
with open(Utils.local_path('lib', 'worlds', 'pokemon_rb', f'basepatch_{game_version}.bsdiff4'), 'rb') as stream:
base_patch = bytes(stream.read())
except FileNotFoundError:
with open(Utils.local_path('worlds', 'pokemon_rb', f'basepatch_{game_version}.bsdiff4'), 'rb') as stream:
base_patch = bytes(stream.read())
base_patched_rom_data = bsdiff4.patch(base_rom, base_patch)
basemd5 = hashlib.md5()
basemd5.update(base_patched_rom_data)

with zipfile.ZipFile(patch_file, 'r') as patch_archive:
with patch_archive.open('delta.bsdiff4', 'r') as stream:
patch = stream.read()
patched_rom_data = bsdiff4.patch(base_patched_rom_data, patch)

written_hash = patched_rom_data[0xFFCB:0xFFDB]
if written_hash == basemd5.digest():
with open(comp_path, "wb") as patched_rom_file:
patched_rom_file.write(patched_rom_data)

async_start(run_game(comp_path))
else:
msg = "Patch supplied was not generated with the same base patch version as this client. Patching failed."
logger.warning(msg)
ctx.gui_error('Error', msg)
patched_rom_data = bsdiff4.patch(base_rom, patch)

with open(comp_path, "wb") as patched_rom_file:
patched_rom_file.write(patched_rom_data)

async_start(run_game(comp_path))


if __name__ == '__main__':
Expand Down
4 changes: 3 additions & 1 deletion WebHostLib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
app.config['MAX_CONTENT_LENGTH'] = 64 * 1024 * 1024 # 64 megabyte limit
# if you want to deploy, make sure you have a non-guessable secret key
app.config["SECRET_KEY"] = bytes(socket.gethostname(), encoding="utf-8")
# at what amount of worlds should scheduling be used, instead of rolling in the webthread
# at what amount of worlds should scheduling be used, instead of rolling in the web-thread
app.config["JOB_THRESHOLD"] = 2
# after what time in seconds should generation be aborted, freeing the queue slot. Can be set to None to disable.
app.config["JOB_TIME"] = 600
app.config['SESSION_PERMANENT'] = True

# waitress uses one thread for I/O, these are for processing of views that then get sent
Expand Down
20 changes: 19 additions & 1 deletion WebHostLib/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import random
import tempfile
import zipfile
import concurrent.futures
from collections import Counter
from typing import Dict, Optional, Any

Expand Down Expand Up @@ -98,7 +99,7 @@ def gen_game(gen_options, meta: Optional[Dict[str, Any]] = None, owner=None, sid
meta.setdefault("server_options", {}).setdefault("hint_cost", 10)
race = meta.setdefault("race", False)

try:
def task():
target = tempfile.TemporaryDirectory()
playercount = len(gen_options)
seed = get_seed()
Expand Down Expand Up @@ -138,6 +139,23 @@ def gen_game(gen_options, meta: Optional[Dict[str, Any]] = None, owner=None, sid
ERmain(erargs, seed, baked_server_options=meta["server_options"])

return upload_to_db(target.name, sid, owner, race)
thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=1)
thread = thread_pool.submit(task)

try:
return thread.result(app.config["JOB_TIME"])
except concurrent.futures.TimeoutError as e:
if sid:
with db_session:
gen = Generation.get(id=sid)
if gen is not None:
gen.state = STATE_ERROR
meta = json.loads(gen.meta)
meta["error"] = (
"Allowed time for Generation exceeded, please consider generating locally instead. " +
e.__class__.__name__ + ": " + str(e))
gen.meta = json.dumps(meta)
commit()
except BaseException as e:
if sid:
with db_session:
Expand Down
5 changes: 0 additions & 5 deletions WebHostLib/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,6 @@ def get_html_doc(option_type: type(Options.Option)) -> str:
if sub_option_id == option.default:
this_option["defaultValue"] = sub_option_name

this_option["options"].append({
"name": "Random",
"value": "random",
})

if option.default == "random":
this_option["defaultValue"] = "random"

Expand Down
90 changes: 81 additions & 9 deletions WebHostLib/static/assets/player-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ const buildOptionsTable = (settings, romOpts = false) => {
const tdr = document.createElement('td');
let element = null;

const randomButton = document.createElement('button');

switch(settings[setting].type){
case 'select':
element = document.createElement('div');
Expand All @@ -138,8 +140,21 @@ const buildOptionsTable = (settings, romOpts = false) => {
}
select.appendChild(option);
});
select.addEventListener('change', (event) => updateGameSetting(event));
select.addEventListener('change', (event) => updateGameSetting(event.target));
element.appendChild(select);

// Randomize button
randomButton.innerText = '🎲';
randomButton.classList.add('randomize-button');
randomButton.setAttribute('data-key', setting);
randomButton.setAttribute('data-tooltip', 'Toggle randomization for this option!');
randomButton.addEventListener('click', (event) => toggleRandomize(event, [select]));
if (currentSettings[gameName][setting] === 'random') {
randomButton.classList.add('active');
select.disabled = true;
}

element.appendChild(randomButton);
break;

case 'range':
Expand All @@ -154,15 +169,29 @@ const buildOptionsTable = (settings, romOpts = false) => {
range.value = currentSettings[gameName][setting];
range.addEventListener('change', (event) => {
document.getElementById(`${setting}-value`).innerText = event.target.value;
updateGameSetting(event);
updateGameSetting(event.target);
});
element.appendChild(range);

let rangeVal = document.createElement('span');
rangeVal.classList.add('range-value');
rangeVal.setAttribute('id', `${setting}-value`);
rangeVal.innerText = currentSettings[gameName][setting] ?? settings[setting].defaultValue;
rangeVal.innerText = currentSettings[gameName][setting] !== 'random' ?
currentSettings[gameName][setting] : settings[setting].defaultValue;
element.appendChild(rangeVal);

// Randomize button
randomButton.innerText = '🎲';
randomButton.classList.add('randomize-button');
randomButton.setAttribute('data-key', setting);
randomButton.setAttribute('data-tooltip', 'Toggle randomization for this option!');
randomButton.addEventListener('click', (event) => toggleRandomize(event, [range]));
if (currentSettings[gameName][setting] === 'random') {
randomButton.classList.add('active');
range.disabled = true;
}

element.appendChild(randomButton);
break;

case 'special_range':
Expand Down Expand Up @@ -201,7 +230,8 @@ const buildOptionsTable = (settings, romOpts = false) => {
let specialRangeVal = document.createElement('span');
specialRangeVal.classList.add('range-value');
specialRangeVal.setAttribute('id', `${setting}-value`);
specialRangeVal.innerText = currentSettings[gameName][setting] ?? settings[setting].defaultValue;
specialRangeVal.innerText = currentSettings[gameName][setting] !== 'random' ?
currentSettings[gameName][setting] : settings[setting].defaultValue;

// Configure select event listener
specialRangeSelect.addEventListener('change', (event) => {
Expand All @@ -210,7 +240,7 @@ const buildOptionsTable = (settings, romOpts = false) => {
// Update range slider
specialRange.value = event.target.value;
document.getElementById(`${setting}-value`).innerText = event.target.value;
updateGameSetting(event);
updateGameSetting(event.target);
});

// Configure range event handler
Expand All @@ -220,13 +250,29 @@ const buildOptionsTable = (settings, romOpts = false) => {
(Object.values(settings[setting].value_names).includes(parseInt(event.target.value))) ?
parseInt(event.target.value) : 'custom';
document.getElementById(`${setting}-value`).innerText = event.target.value;
updateGameSetting(event);
updateGameSetting(event.target);
});

element.appendChild(specialRangeSelect);
specialRangeWrapper.appendChild(specialRange);
specialRangeWrapper.appendChild(specialRangeVal);
element.appendChild(specialRangeWrapper);

// Randomize button
randomButton.innerText = '🎲';
randomButton.classList.add('randomize-button');
randomButton.setAttribute('data-key', setting);
randomButton.setAttribute('data-tooltip', 'Toggle randomization for this option!');
randomButton.addEventListener('click', (event) => toggleRandomize(
event, [specialRange, specialRangeSelect])
);
if (currentSettings[gameName][setting] === 'random') {
randomButton.classList.add('active');
specialRange.disabled = true;
specialRangeSelect.disabled = true;
}

specialRangeWrapper.appendChild(randomButton);
break;

default:
Expand All @@ -243,17 +289,43 @@ const buildOptionsTable = (settings, romOpts = false) => {
return table;
};

const toggleRandomize = (event, inputElements) => {
const active = event.target.classList.contains('active');
const randomButton = event.target;

if (active) {
randomButton.classList.remove('active');
for (const element of inputElements) {
element.disabled = undefined;
updateGameSetting(element);
}
} else {
randomButton.classList.add('active');
for (const element of inputElements) {
element.disabled = true;
updateGameSetting(randomButton);
}
}
};

const updateBaseSetting = (event) => {
const options = JSON.parse(localStorage.getItem(gameName));
options[event.target.getAttribute('data-key')] = isNaN(event.target.value) ?
event.target.value : parseInt(event.target.value);
localStorage.setItem(gameName, JSON.stringify(options));
};

const updateGameSetting = (event) => {
const updateGameSetting = (settingElement) => {
const options = JSON.parse(localStorage.getItem(gameName));
options[gameName][event.target.getAttribute('data-key')] = isNaN(event.target.value) ?
event.target.value : parseInt(event.target.value, 10);

if (settingElement.classList.contains('randomize-button')) {
// If the event passed in is the randomize button, then we know what we must do.
options[gameName][settingElement.getAttribute('data-key')] = 'random';
} else {
options[gameName][settingElement.getAttribute('data-key')] = isNaN(settingElement.value) ?
settingElement.value : parseInt(settingElement.value, 10);
}

localStorage.setItem(gameName, JSON.stringify(options));
};

Expand Down
19 changes: 19 additions & 0 deletions WebHostLib/static/styles/player-settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ html{
flex-grow: 1;
}

#player-settings table select:disabled{
background-color: lightgray;
}

#player-settings table .range-container{
display: flex;
flex-direction: row;
Expand All @@ -138,12 +142,27 @@ html{
#player-settings table .special-range-wrapper{
display: flex;
flex-direction: row;
margin-top: 0.25rem;
}

#player-settings table .special-range-wrapper input[type=range]{
flex-grow: 1;
}

#player-settings table .randomize-button {
max-height: 24px;
line-height: 16px;
padding: 2px 8px;
margin: 0 0 0 0.25rem;
font-size: 12px;
border: 1px solid black;
border-radius: 3px;
}

#player-settings table .randomize-button.active {
background-color: #ffef00; /* Same as .interactive in globalStyles.css */
}

#player-settings table label{
display: block;
min-width: 200px;
Expand Down
1 change: 1 addition & 0 deletions WebHostLib/static/styles/themes/dirt.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pre{

pre code{
border: none;
display: block;
}

code{
Expand Down
1 change: 1 addition & 0 deletions WebHostLib/static/styles/themes/grass-flowers.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pre{

pre code{
border: none;
display: block;
}

code{
Expand Down
1 change: 1 addition & 0 deletions WebHostLib/static/styles/themes/grass.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pre{

pre code{
border: none;
display: block;
}

code{
Expand Down
1 change: 1 addition & 0 deletions WebHostLib/static/styles/themes/ice.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pre{

pre code{
border: none;
display: block;
}

code{
Expand Down
1 change: 1 addition & 0 deletions WebHostLib/static/styles/themes/jungle.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pre{

pre code{
border: none;
display: block;
}

code{
Expand Down
1 change: 1 addition & 0 deletions WebHostLib/static/styles/themes/ocean.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pre{

pre code{
border: none;
display: block;
}

code{
Expand Down
1 change: 1 addition & 0 deletions WebHostLib/static/styles/themes/party-time.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pre{

pre code{
border: none;
display: block;
}

code{
Expand Down
1 change: 1 addition & 0 deletions WebHostLib/static/styles/themes/stone.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pre{

pre code{
border: none;
display: block;
}

code{
Expand Down
13 changes: 13 additions & 0 deletions WebHostLib/templates/minecraftTracker.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@
<td><img src="{{ icons['Fishing Rod'] }}" class="{{ 'acquired' if 'Fishing Rod' in acquired_items }}" title="Fishing Rod" /></td>
<td><img src="{{ icons['Campfire'] }}" class="{{ 'acquired' if 'Campfire' in acquired_items }}" title="Campfire" /></td>
<td><img src="{{ icons['Spyglass'] }}" class="{{ 'acquired' if 'Spyglass' in acquired_items }}" title="Spyglass" /></td>
<td>
<div class="counted-item">
<img src="{{ icons['Dragon Egg Shard'] }}" class="{{ 'acquired' if 'Dragon Egg Shard' in acquired_items }}" title="Dragon Egg Shard" />
<div class="item-count">{{ shard_count }}</div>
</div>
</td>
</tr>
<tr>
<td><img src="{{ icons['Lead'] }}" class="{{ 'acquired' if 'Lead' in acquired_items }}" title="Lead" /></td>
<td><img src="{{ icons['Saddle'] }}" class="{{ 'acquired' if 'Saddle' in acquired_items }}" title="Saddle" /></td>
<td><img src="{{ icons['Channeling Book'] }}" class="{{ 'acquired' if 'Channeling Book' in acquired_items }}" title="Channeling Book" /></td>
<td><img src="{{ icons['Silk Touch Book'] }}" class="{{ 'acquired' if 'Silk Touch Book' in acquired_items }}" title="Silk Touch Book" /></td>
<td><img src="{{ icons['Piercing IV Book'] }}" class="{{ 'acquired' if 'Piercing IV Book' in acquired_items }}" title="Piercing IV Book" /></td>
</tr>
</table>
<table id="location-table">
Expand Down
Loading

0 comments on commit dcf4108

Please sign in to comment.