Skip to content

Commit

Permalink
Tidying
Browse files Browse the repository at this point in the history
  • Loading branch information
undeadjess committed Oct 23, 2024
1 parent 4c765d8 commit c4d5e3e
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 93 deletions.
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,31 @@ Assuming you have docker and docker-compose installed, you can deploy ServerJars
wget https://raw.githubusercontent.com/undeadjess/mcserverjars/main/docker-compose.yml
docker-compose up -d
```
ServerJars will then be available on port 80

## API Usage:
`GET /<type>/<jar>/<version>/<build>`
- type: The type of the server jar. (Server, Proxys coming soon!)
`GET /api/<type>/<jar>/<version>/<build>`
- type: The type of the server jar. (Servers, Proxies and more coming soon!)
- jar: The server jar file to download. (vanilla, paper, forge)
- version: The minecraft version of the jar. (1.16.5, 1.17.1)
- build: The build number of the server jar. Only for non-vanilla servers (1, 2, 3, ...)

If the build number is not specified, the latest build will be returned.
If neither the version or build number is specified, the latest version will be returned.
Both `version` and `build` are optional. if none are specified, the latest version will be returned

#### Examples:
`GET /server/paper/1.17.1/142`
`GET /api/server/paper/1.17.1/142`
Returns the download link for the 142nd build of the 1.17.1 paper server jar.

`GET /server/paper/1.16.5`
`GET /api/server/paper/1.16.5`
Returns the download link for the latest build of the 1.16.5 paper server jar.

`GET /server/paper`
`GET /api/server/paper`
Returns the download link for the latest build of the latest version of the paper server jar.

## To-Do:
## Future Plans:
- Add support for proxys (velocity, bungeecord, geyser...)
- Add support for more server jars (only vanilla, paper, and purpur are supported at this time)
- build bukkit and spigot jars and store them in a cache
- squash bugs

## FAQ:
- Why does ServerJars use a database instead of simply fetching the jars from the official websites?
Expand Down
40 changes: 15 additions & 25 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ const dbName = process.env.DB_NAME;



// mysql connection
// var con = mysql.createConnection({
// host: dbHost,
// user: dbUser,
// password: dbPassword,
// database: dbName
// });

// mysql connection pool
var con = mysql.createPool({
connectionLimit: 10,
Expand All @@ -37,6 +29,7 @@ let validServers = [];

function getValidServers() {
return new Promise((resolve, reject) => {
// get all server types from database
con.query('SELECT type FROM server_types', function (err, result) {
if (err) {
console.log('[getValidServers] error getting servers:', err);
Expand All @@ -60,6 +53,7 @@ function getValidServers() {
async function initialize() {
while (true) {
try {
// connect to mysql
await new Promise((resolve, reject) => {
con.getConnection((err, connection) => {
if (err) {
Expand Down Expand Up @@ -109,6 +103,7 @@ app.get('/servers/:server/:version?/:build?', (req, res) => {
console.log('[routes] New request to', req.path, " from IP address:", req.ip);
const { server, version, build } = req.params;

// get server URL. if version and build are not provided, pass nothing to the function
getServerURL(server, version || null, build || null).then((data) => {
res.json(data);
}).catch(err => {
Expand All @@ -125,19 +120,17 @@ function getServerURL(server, version, build) {

// Make sure values are valid to prevent SQL injection
if (!(validServers.includes(server))) {
return resolve({ error: 'invalid server' });
return reject({ error: 'invalid server' });
}
if (version && !version.match(/\d+\.\d+(\.\d+)?/)) {
return resolve({ error: 'invalid version' });
return reject({ error: 'invalid version' });
}
if (build && !build.match(/\d+/)) {
return resolve({ error: 'invalid build' });
return reject({ error: 'invalid build' });
}

// set query and params based on input
console.log('[getServerURL] getting server urls for', server, version, build);
let query;
let paramsGetLatest;
let queryGetAllBuilds;
let queryGetAllVersions;

Expand All @@ -149,7 +142,7 @@ function getServerURL(server, version, build) {
queryGetAllBuilds = `SELECT build FROM ${server} WHERE version = ? ORDER BY CAST(build AS UNSIGNED) DESC`;
params = [version];
} else {
// select the latest version and build - sort by version and build, but treat them as unsigned integers so that they sort correctly (oww my brain hurtssss from making this)
// select the latest version and build - sort by version and build, but treat them as unsigned integers so that they sort correctly.
queryGetLatest = `
SELECT download_url
FROM ${server}
Expand All @@ -166,10 +159,11 @@ function getServerURL(server, version, build) {
`;
// get just of all versions to display after latest - dont need to sort by build
queryGetAllVersions = `
SELECT DISTINCT version FROM ${server} ORDER BY
CAST(SUBSTRING_INDEX(version, '.', 1) AS UNSIGNED) DESC,
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(version, '.', 2), '.', -1) AS UNSIGNED) DESC,
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(version, '.', -1), '.', -1) AS UNSIGNED) DESC
SELECT DISTINCT version FROM ${server}
ORDER BY
CAST(SUBSTRING_INDEX(version, '.', 1) AS UNSIGNED) DESC,
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(version, '.', 2), '.', -1) AS UNSIGNED) DESC,
CAST(COALESCE(SUBSTRING_INDEX(SUBSTRING_INDEX(version, '.', -1), '.', -1), '0') AS UNSIGNED) DESC
`;
params = [];
}
Expand All @@ -181,12 +175,8 @@ function getServerURL(server, version, build) {
console.log('[getServerURL] got server urls:', result[0] ? result[0].download_url : null);

// add version and build as latest if they don't exist -- IMPROVE THIS LATER!!!
if (!version) {
version = "API data coming soon!";
}
if (!build) {
build = "API data coming soon!";
}
version = result[0] ? result[0].version : null;
build = result[0] ? result[0].build : null;

// if download_url is null, error out
if (!result[0]) {
Expand Down Expand Up @@ -222,7 +212,7 @@ function getServerURL(server, version, build) {
resolve(response);
});
} else {
resolve(response); // basically just give up and dont give anyhting (shouldnt happen but just in case :P)
resolve(response); // basically just give up and dont give anything (shouldnt happen but just in case :P)
}
}
});
Expand Down
90 changes: 33 additions & 57 deletions fetcher/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ const dbHost = process.env.DB_HOST;
const dbUser = process.env.DB_USER;
const dbPassword = process.env.DB_PASSWORD;
const dbName = process.env.DB_NAME;
const updateInterval = process.env.UPDATE_INTERVAL || 3600000; // 1 hour



const pool = mysql.createPool({
connectionLimit: 10, // i dont actually know how many it will use but 10 seems safe lol
connectionLimit: 10,
host: dbHost,
user: dbUser,
password: dbPassword,
Expand All @@ -19,68 +20,43 @@ const pool = mysql.createPool({



// const serverTypes = ["vanilla", "paper", "purpur", "spigot", "bukkit", "forge", "fabric"];
const serverTypes = ["vanilla", "paper", "purpur", "fabric"]; // actually working server types - initializeDatabase() will create tables for these types
const serverTypes = ["vanilla", "paper", "purpur", "fabric"];



// get a list of minecraft versions
function getMinecraftVersions() {
return new Promise((resolve, reject) => {
var mcversions = [];
console.log('[getMinecraftVersions] Fetching minecraft versions');
url = 'https://launchermeta.mojang.com/mc/game/version_manifest.json';

fetch(url)
.then(response => response.json())
.then(data => {
versions = data.versions;
versions.forEach(version => {
if (version.type === 'release') {
mcversions.push({"version":version.id.toString(), "url":version.url.toString()}); // Add the version to the results
}
});
resolve(mcversions); // Resolve the promise with the results
}).then(() => {
console.log('[getMinecraftVersions] Finished Fetching Minecraft Versions');

})
.catch(error => {
console.log('[getMinecraftVersions] error:', error);
resolve(mcversions); // Resolve the promise even if there's an error
});
});
}

minecraftversions = getMinecraftVersions()
async function getVanillaServerURLs() {
console.log('[getMinecraftServerURLs] Fetching Minecraft versions and server URLs');

try {
const versionsResponse = await fetch('https://launchermeta.mojang.com/mc/game/version_manifest.json');
const versionsData = await versionsResponse.json();

const mcversions = versionsData.versions.filter(version => version.type === 'release');

const fetchPromises = mcversions.map(async (version) => {
try {
const response = await fetch(version.url);
const data = await response.json();
return { version: version.id, downloadURL: data.downloads.server?.url }; // Optional chaining
} catch (error) {
console.log(`[getMinecraftServerURLs] error getting ${version.url}:`, error);
return null;
}
});

const results = await Promise.all(fetchPromises);
const validResults = results.filter(result => result !== null);

console.log('[getMinecraftServerURLs] Finished fetching Minecraft server URLs');
return validResults;

// server scripts
// vanilla
async function getVanillaServerURLs() {
const vanillaServerURLs = [];
console.log('[getVanillaServerURLs] Fetching Vanilla Server URLs');
const mcversions = await minecraftversions;
} catch (error) {
console.log('[getMinecraftServerURLs] error:', error);
return []; // Return an empty array on error
}
}

const fetchPromises = mcversions.map(async (version) => {
try {
const response = await fetch(version.url);
const data = await response.json();
// TODO - do something about the error for minecraft versions with no multiplayer server jar
return { version: version.version, downloadURL: data.downloads.server.url };
} catch (error) {
console.log(`[getVanillaServerURLs] error getting ${version.url}:`, error);
return null;
}
});

const results = await Promise.all(fetchPromises);
const validResults = results.filter(result => result !== null);

console.log('[getVanillaServerURLs] Finished Fetching Vanilla Server URLs');
return validResults;
}

// paper
async function getPaperServerURLs() {
Expand Down Expand Up @@ -249,7 +225,7 @@ async function getFabricServerURLs() {
// split the version string into an array of numbers
const versionNumbers = version.split('.').map(Number)
// discard any array items after the first 2
versionNumbers.length = 2;
versionNumbers.length = 2; //maybe redundant?
// check if the second number is less than 12, else return the version
if (versionNumbers[1] < 12) {
return;
Expand Down Expand Up @@ -396,7 +372,7 @@ async function initializeDatabase() {
async function main() {
await initializeDatabase();
await updateDatabase();
setInterval(updateDatabase, 3600000); // 3600000 = 1 hour
setInterval(updateDatabase, updateInterval);
}

main();
2 changes: 1 addition & 1 deletion web/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ app.get('/', (req, res) => {
// serve public/ directory
app.use(express.static('public'));

// serve html files in public/ directory
// let html files be accessed without file extension
app.use(express.static('public', {
extensions: ['html']
}));
Expand Down
3 changes: 2 additions & 1 deletion web/public/assets/js/downloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ serverTypeSelector.addEventListener("change", function() {

// set version selector to the latest version
serverVersionSelector.selectedIndex = 0;
serverVersionSelector.dispatchEvent(new Event("change"));

// enable version selector and disable others
serverVersionSelector.disabled = false;
serverBuildSelector.innerHTML = "";
serverBuildSelector.disabled = true;
downloadButton.disabled = true;
})
.catch((error) => console.error("Error fetching server versions:", error));
Expand Down Expand Up @@ -101,6 +101,7 @@ serverVersionSelector.addEventListener("change", function() {

// set version selector to latest version
serverBuildSelector.selectedIndex = 0;
serverBuildSelector.dispatchEvent(new Event("change"));

// enable build selector
serverBuildSelector.disabled = false;
Expand Down

0 comments on commit c4d5e3e

Please sign in to comment.