Compare commits

..

10 Commits

Author SHA1 Message Date
thayol c2fc1ffa64 Fixed "desynced" bug 2021-06-20 08:12:28 +02:00
thayol 310a716304 Introduced shutdown privilege. 2021-06-17 22:10:34 +02:00
thayol e51988a57d Fixed MD formatting. 2021-06-17 22:10:34 +02:00
thayol cbf030028c The starting request is now shown. 2021-06-17 22:10:33 +02:00
thayol db0c440d1c Added a shutdown timer 2021-06-17 22:10:33 +02:00
thayol 44eaa2b086 Added auto-shutdown 2021-06-17 22:10:32 +02:00
thayol d4ba9e3f55 Removed useless code 2021-06-17 22:10:32 +02:00
thayol 7a1c1e09f7 Refactored to "is (not)" 2021-06-17 22:10:31 +02:00
thayol a3dfa05bb2 Removed leftovers from non-TLS 2021-06-17 22:10:31 +02:00
thayol 7bf7b0c656 Updated README 2021-06-17 22:10:30 +02:00
14 changed files with 74 additions and 59 deletions
+2 -6
View File
@@ -1,5 +1,4 @@
<?php
// http://zovguran.net/Unalike/API
include "../api_key.php";
if (!empty($_GET["username"]) || !empty($_GET["userid"]))
@@ -26,10 +25,7 @@ if (!empty($_GET["username"]) || !empty($_GET["userid"]))
$id = $_GET["userid"];
}
if ($id == "~Unalike")
{
}
else if ($id < 0)
else if ($id != "~Unalike" && $id < 0)
{
echo "Unauthorized";
exit(0);
@@ -217,7 +213,7 @@ if (!empty($_GET["username"]) || !empty($_GET["userid"]))
}
else if ($diffs_redirect)
{
header("Location: " . "../f/" . strval($beatmapset));
header("Location: ../f/" . strval($beatmapset));
}
}
}
-1
View File
@@ -1,6 +1,5 @@
<?php
session_start();
// http://zovguran.net/Unalike/OAuth/
if (!empty($_GET["error"]) && $_GET["error"] == "access_denied")
{
+14 -14
View File
@@ -36,16 +36,16 @@ Even though I doubt this would be easy to develop without a complete rewrite, pu
## Setup
1. Clone the source code to a subfolder of your web server.
2. Copy the files from `setup_help/` to the root of Unalike. Guide [here][setup-help-guide].
3. Fill in the missing keys in the newly copied files.
4. (Optional) Check the configuration section of unalike.py
5. Set up a URL rewrite rule that makes `path/to/unalike/api/USERNAME/KEY/VALUE` point to `path/to/unalike/API/?username=USERNAME&KEY=VALUE` (You can just rewrite these calls manually if you want to, but using API parameters like this is very user friendly.)
1. Copy the files from `setup_help/` to the root of Unalike. Guide [here][setup-help-guide].
1. Fill in the missing keys in the newly copied files.
1. (Optional) Check the configuration section of unalike.py
1. Set up a URL rewrite rule that makes `path/to/unalike/api/USERNAME/KEY/VALUE` point to `path/to/unalike/API/?username=USERNAME&KEY=VALUE` (You can just rewrite these calls manually if you want to, but using API parameters like this is very user friendly.)
## Start
1. Start start.ps1 with powershell.
2. Start your web service if it is stopped.
1. Start your web service if it is stopped.
*(If it's your first time running start.ps1, the service will start automatically.)*
@@ -53,15 +53,15 @@ Even though I doubt this would be easy to develop without a complete rewrite, pu
## Usage
1. Open the web page you deployed in a web browser.
2. Log in with you osu! account.
3. Press the "Start" button if Unalike is offline.
4. Press the "New lobby" button.
5. Make sure your osu! client is open and connected to Bancho.
6. Press the "Invite" button next of the newly created lobby.
7. Press F9 in your osu! client to open Bancho, then click the invite link received.
8. Wait for Unalike to give you the Host.
9. Pick a map, then ready up to start playing.
10. After playing, don't forget to press the "Shut down" button to save resources.
1. Log in with you osu! account.
1. Press the "Start" button if Unalike is offline.
1. Press the "New lobby" button.
1. Make sure your osu! client is open and connected to Bancho.
1. Press the "Invite" button next of the newly created lobby.
1. Press F9 in your osu! client to open Bancho, then click the invite link received.
1. Wait for Unalike to give you the Host.
1. Pick a map, then ready up to start playing.
1. After playing, don't forget to press the "Shut down" button to save resources.
*(Optionally, you can replace step six with pressing the "Send invites" button.)*
-4
View File
@@ -1,9 +1,5 @@
<?php
session_start();
// http://zovguran.net/Unalike/action/?(a|b|c)
// header("Content-Type: application/json");
// echo json_encode($_GET);
if (!empty($_SESSION["unalike-osu-id"]) && !empty($_SESSION["unalike-osu-username"]) && !empty($_SESSION["unalike-granted"]) && $_SESSION["unalike-granted"] === true)
{
-1
View File
@@ -1,6 +1,5 @@
<?php
session_start();
// http://zovguran.net/Unalike/async/
$unalike = json_decode(file_get_contents("../unalike.json"), true);
// if (!empty($unalike))
-1
View File
@@ -1,6 +1,5 @@
<?php
session_start();
// http://zovguran.net/Unalike/async/
$relative_prefix = "../../lobbies/";
$original_suffix = ".json";
+3 -4
View File
@@ -1,6 +1,5 @@
<?php
session_start();
// http://zovguran.net/Unalike/async/
$api_url = "http://localhost:80/Unalike/API";
@@ -188,10 +187,10 @@ if (isset($_GET["render"]))
{
$status = '<span class="positive-color">FC</span>';
}
else
{
// else
// {
// $status = '<span class="positive-color">PASS</span>';
}
// }
$mode_text = "?";
if ($score["game"]["mode"] == "osu")
-1
View File
@@ -1,6 +1,5 @@
<?php
session_start();
// http://zovguran.net/Unalike/
$authenticated = false;
include "api_key.php";
-1
View File
@@ -1,5 +1,4 @@
<?php
// http://zovguran.net/Unalike/login/
include "../api_key.php";
$scope = implode("+", [ "identify", "public" ]);
-1
View File
@@ -1,6 +1,5 @@
<?php
session_start();
// http://zovguran.net/Unalike/logout
unset($_SESSION["unalike-osu-id"]);
unset($_SESSION["unalike-osu-username"]);
unset($_SESSION["unalike-granted"]);
+1 -1
View File
@@ -16,7 +16,7 @@ For the sake of readability, I'll list the basic steps here.
## osu! API Authentication
- Copy `/setup_help/api_key.php` to `/api_key.php`
- Change the `$api_key` variable's contents to your `API Key` from the [API Registration][osu-api-v1-url] page.
- Change the `$api_key` variable's contents to your "API Key" from the [API Registration][osu-api-v1-url] page.
- Register a new OAuth application in your [profile settings][osu-api-v2-url].
- Change the `$client_id`, `$client_secret`, and `$callback_uri` to their given values respectively.
+1
View File
@@ -13,6 +13,7 @@ while($true)
else
{
Write-Host "[Unalike] Starting IRC bot..."
Write-Host "Request: $content"
Set-Content -Path $file -Value "{}"
$flags = "unalike.py"
$flagArray = $flags -split " "
+46 -25
View File
@@ -7,7 +7,7 @@ import random
import json
import math
import msvcrt
import os.path
import os
from os import path
# CONFIGURATION
@@ -34,8 +34,11 @@ lobby_default_size = 1
# checks per second (Hz) [a range between 0.5 and 4 is recommended, can be any arbitrary number]
polling_rate = 2 # 2 = report to the web api every 0.5 seconds (also affects IRC ping)
# the time after the script will exit itself
global_shutdown_timer = 10 * 60 # in seconds (if it is too high, weird timeout issues start to appear)
# this will be used in chat messages (can be anything, does not have to point to your Unalike)
unalike_url = "http://zovguran.net/Unalike/"
unalike_url = "https://zovguran.net/Unalike/"
# change it to match your location of the Unalike API (does not have to be local)
unalike_api = "http://localhost:80/Unalike/API"
@@ -80,6 +83,10 @@ bot_pass = ""
lobby_default_pass = "unset"
local_secret = "unset"
current_shutdown_timer = 0
global_session_admin = ""
# folder structure setup
os.makedirs(lobbies_dir, exist_ok=True)
@@ -159,7 +166,7 @@ def irc_send_links(recipient, channel_id=False):
temp_lobbies = []
counter = 1
if channel_id != False and channel_id in managed_lobbies:
if channel_id is not False and channel_id in managed_lobbies:
temp_lobbies.append("[" + "osump://" + str(managed_lobbies[channel_id]["lobby"]) + "/" + str(managed_lobbies[channel_id]["password"]) + " " + str(channel_id) + "]")
counter += 1
else:
@@ -198,7 +205,7 @@ def irc_sync_lobbies_to(originating_channel, beatmapset_id, beatmap_id):
if lobby != originating_channel and "beatmapset" in managed_lobbies[lobby] and managed_lobbies[lobby]["beatmapset"] != beatmapset_id:
skipSync = False
if "desynced" in managed_lobbies[lobby]:
if managed_lobbies[lobby]["desynced"] == True:
if managed_lobbies[lobby]["desynced"] is True:
skipSync = True
if not skipSync:
@@ -253,7 +260,7 @@ def irc_start_managing(lobby_channel, lobby_name=False, join=False):
managed_lobbies[lobby_channel] = {}
managed_lobbies[lobby_channel]["channel"] = lobby_channel
if lobby_name != False:
if lobby_name is not False:
managed_lobbies[lobby_channel]["name"] = lobby_name
if join:
managed_lobbies[lobby_channel]["skipModeSetup"] = True
@@ -303,7 +310,7 @@ def irc_to_Command(lines):
cmd.channel = expl[args_start+1]
temp_msg = " ".join(expl[(args_start+1):])
if len(temp_msg) > 1:
cmd.message = temp_msg[1:].replace(b'\x01ACTION'.decode(encoding), "[STATUS]").replace(b'\x01'.decode(encoding), "");
cmd.message = temp_msg[1:].replace(b'\x01ACTION'.decode(encoding), "[STATUS]").replace(b'\x01'.decode(encoding), "")
cmds.append(cmd)
@@ -332,8 +339,8 @@ def irc_read():
if text == "":
return []
else:
return [x for x in text.split("\n") if len(x.strip()) > 0]
return [x for x in text.split("\n") if len(x.strip()) > 0]
def reset_lobby_states():
global global_playing, managed_lobbies, lobbies_changed
@@ -416,12 +423,15 @@ while running:
for request in request_json:
if "type" in request:
if request["type"] == "invite" and "target" in request:
filter = False;
if "filter" in request:
filter = fix_mp_prefix(request["filter"])
if global_session_admin == "" and "issuer" in request and "username" in request["issuer"]:
global_session_admin = request["issuer"]["username"]
irc_send_links(request["target"].replace(" ", "_"), filter)
if request["type"] == "invite" and "target" in request:
the_filter = False
if "filter" in request:
the_filter = fix_mp_prefix(request["filter"])
irc_send_links(request["target"].replace(" ", "_"), the_filter)
elif request["type"] == "new_lobby":
if len(managed_lobbies) < global_max_lobbies:
lobby_name = "Unalike"
@@ -451,8 +461,10 @@ while running:
print("Registering lobby: " + str(request["target"]))
irc_start_managing(request["target"], join=True)
elif request["type"] == "shutdown":
running = False
break
if global_session_admin != "" and "issuer" in request and "username" in request["issuer"] and global_session_admin == request["issuer"]["username"]:
running = False
break
for line in lines:
if line.cmd in [ "001" ]:
@@ -615,7 +627,7 @@ while running:
skipSync = False
if "desynced" in managed_lobbies[lobby_channel]:
if managed_lobbies[lobby_channel]["desynced"] == True:
if managed_lobbies[lobby_channel]["desynced"] is True:
skipSync = True
if skipSync:
@@ -717,19 +729,23 @@ while running:
temp_output["playing"] = global_playing
temp_output["apiPlayer"] = api_player
temp_output["roundsPlayed"] = global_rounds_played
temp_output["timestamp"] = math.floor(time.time());
temp_output["boot"] = boot_timestamp;
temp_output["delay"] = global_irc_send_timeout;
temp_output["maxLobbies"] = global_max_lobbies;
temp_output["current_mapset"] = current_mapset;
temp_output["timestamp"] = math.floor(time.time())
temp_output["shutdownTimer"] = math.floor(global_shutdown_timer - current_shutdown_timer)
temp_output["boot"] = boot_timestamp
temp_output["delay"] = global_irc_send_timeout
temp_output["maxLobbies"] = global_max_lobbies
temp_output["currentMapset"] = current_mapset
temp_output["sessionAdmin"] = global_session_admin
# uncomment to expose commands to the public
# temp_output["command_queue"] = global_irc_send_queue;
# temp_output["command_queue"] = global_irc_send_queue
with open(report_file, "w") as outfile:
json.dump(temp_output, outfile)
current_shutdown_timer += global_polling_rate
if lobbies_changed:
current_shutdown_timer = 0
lobbies_changed = False
all_ready = True
all_finished = True
@@ -757,9 +773,9 @@ while running:
irc_send_pm(channel_id, "!mp set 0 1 " + str(lobby_default_size))
lobbies_changed = True
if managed_lobbies[channel_id]["ready"] == False:
if managed_lobbies[channel_id]["ready"] is False:
all_ready = False
if managed_lobbies[channel_id]["playing"] == True:
if managed_lobbies[channel_id]["playing"] is True:
all_finished = False
with open(lobbies_dir + managed_lobbies[channel_id]["match"] + ".json", "w") as json_file:
json.dump(managed_lobbies[channel_id], json_file)
@@ -777,7 +793,7 @@ while running:
if "roundsPlayed" in managed_lobbies[channel_id] and "match" in managed_lobbies[channel_id]:
request_matches.append(str(managed_lobbies[channel_id]["match"]) + ",-1")
composer_url = unalike_composer + "secret=" + local_secret + "&source=" + ";".join(request_matches) + "&beatmapset=" + str(current_mapset);
composer_url = unalike_composer + "secret=" + local_secret + "&source=" + ";".join(request_matches) + "&beatmapset=" + str(current_mapset)
print("Finished. Request forwarded to: Unalike Composer")
@@ -825,6 +841,11 @@ while running:
temp_message = input("Message: ")
irc_send_pm(temp_channel, temp_message)
if current_shutdown_timer > global_shutdown_timer:
print("Shutting down due to inactivity.")
running = False
break
print("")
print("--- END ---")
print("")
+9 -1
View File
@@ -132,6 +132,14 @@ function updateUnalikeDisplay(unalikeJson) {
if (unalikeJson.delay) {
newStatus += "</p><p>Current delay: " + unalikeJson.delay + " seconds between commands. (~" + unalikeJson.delay*4 + " seconds to create a lobby.)";
}
if (unalikeJson.shutdownTimer) {
newStatus += "</p><p>If nothing happens, Unalike will shut down in " + unalikeJson.shutdownTimer + " seconds.";
}
if (unalikeJson.sessionAdmin) {
newStatus += "</p><p>" + unalikeJson.sessionAdmin + " was the first to interact with Unalike. Only he/she can shut it down on command.";
}
// dynamicJsonElement = document.getElementById("dynamic-json");
// dynamicJsonElement.innerHTML = JSON.stringify(unalikeJson);
@@ -238,7 +246,7 @@ function updateUnalikeDisplay(unalikeJson) {
if (lobby.desynced) {
stateSymbol = "🔀 (Desynced)";
}
else if (lobby.beatmapset > 0 && lobby.beatmapset != unalikeJson.current_mapset)
else if (lobby.beatmapset > 0 && lobby.beatmapset != unalikeJson.currentMapset)
{
stateSymbol = "🆘 (Desynced)";
}