Better responsive UI, added author field and improved project loading.

This commit is contained in:
天クマ 2025-03-28 20:17:21 -03:00
commit ea805dbb28
15 changed files with 176 additions and 198 deletions

BIN
1.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 B

View file

@ -1,130 +0,0 @@
var obfuscators = [];
var styleMap = {
'§4': 'font-weight:normal;text-decoration:none;color:#be0000',
'§c': 'font-weight:normal;text-decoration:none;color:#fe3f3f',
'§6': 'font-weight:normal;text-decoration:none;color:#d9a334',
'§e': 'font-weight:normal;text-decoration:none;color:#fefe3f',
'§2': 'font-weight:normal;text-decoration:none;color:#00be00',
'§a': 'font-weight:normal;text-decoration:none;color:#3ffe3f',
'§b': 'font-weight:normal;text-decoration:none;color:#3ffefe',
'§3': 'font-weight:normal;text-decoration:none;color:#00bebe',
'§1': 'font-weight:normal;text-decoration:none;color:#0000be',
'§9': 'font-weight:normal;text-decoration:none;color:#3f3ffe',
'§d': 'font-weight:normal;text-decoration:none;color:#fe3ffe',
'§5': 'font-weight:normal;text-decoration:none;color:#be00be',
'§f': 'font-weight:normal;text-decoration:none;color:#ffffff',
'§7': 'font-weight:normal;text-decoration:none;color:#bebebe',
'§8': 'font-weight:normal;text-decoration:none;color:#3f3f3f',
'§0': 'font-weight:normal;text-decoration:none;color:#000000',
'§l': 'font-weight:bold',
'§n': 'text-decoration:underline;text-decoration-skip:spaces',
'§o': 'font-style:italic',
'§m': 'text-decoration:line-through;text-decoration-skip:spaces',
};
function obfuscate(string, elem) {
var magicSpan,
currNode,
len = elem.childNodes.length;
if(string.indexOf('<br>') > -1) {
elem.innerHTML = string;
for(var j = 0; j < len; j++) {
currNode = elem.childNodes[j];
if(currNode.nodeType === 3) {
magicSpan = document.createElement('span');
magicSpan.innerHTML = currNode.nodeValue;
elem.replaceChild(magicSpan, currNode);
init(magicSpan);
}
}
} else {
init(elem, string);
}
function init(el, str) {
var i = 0,
obsStr = str || el.innerHTML,
len = obsStr.length;
obfuscators.push( window.setInterval(function () {
if(i >= len) i = 0;
obsStr = replaceRand(obsStr, i);
el.innerHTML = obsStr;
i++;
}, 0) );
}
function randInt(min, max) {
return Math.floor( Math.random() * (max - min + 1) ) + min;
}
function replaceRand(string, i) {
var randChar = String.fromCharCode( randInt(64,90) ); /*Numbers: 48-57 Al:64-90*/
return string.substr(0, i) + randChar + string.substr(i + 1, string.length);
}
}
function applyCode(string, codes) {
var len = codes.length;
var elem = document.createElement('span'),
obfuscated = false;
for(var i = 0; i < len; i++) {
elem.style.cssText += styleMap[codes[i]] + ';';
if(codes[i] === '§k') {
obfuscate(string, elem);
obfuscated = true;
}
}
if(!obfuscated) elem.innerHTML = string;
return elem;
}
function parseStyle(string) {
var codes = string.match(/§.{1}/g) || [],
indexes = [],
apply = [],
tmpStr,
indexDelta,
noCode,
final = document.createDocumentFragment(),
len = codes.length,
string = string.replace(/\n|\\n/g, '<br>');
for(var i = 0; i < len; i++) {
indexes.push( string.indexOf(codes[i]) );
string = string.replace(codes[i], '\x00\x00');
}
if(indexes[0] !== 0) {
final.appendChild( applyCode( string.substring(0, indexes[0]), [] ) );
}
for(var i = 0; i < len; i++) {
indexDelta = indexes[i + 1] - indexes[i];
if(indexDelta === 2) {
while(indexDelta === 2) {
apply.push ( codes[i] );
i++;
indexDelta = indexes[i + 1] - indexes[i];
}
apply.push ( codes[i] );
} else {
apply.push( codes[i] );
}
if( apply.lastIndexOf('§r') > -1) {
apply = apply.slice( apply.lastIndexOf('§r') + 1 );
}
tmpStr = string.substring( indexes[i], indexes[i + 1] );
final.appendChild( applyCode(tmpStr, apply) );
}
return final;
}
function clearObfuscators() {
var i = obfuscators.length;
for(;i--;) {
clearInterval(obfuscators[i]);
}
obfuscators = [];
}
String.prototype.replaceColorCodes = function() {
clearObfuscators();
var outputString = parseStyle(String(this));
return outputString;
};
/////////////////////////////////////////////////
function cutString(str, cutStart, cutEnd){
return str.substr(0,cutStart) + str.substr(cutEnd+1);
}

30
featured.js Normal file
View file

@ -0,0 +1,30 @@
const featuredHelper = document.querySelector("#featuredHelper");
async function getFeaturedJSON() {
const response = await fetch(`featured.json`);
if (!response.ok) {
featuredHelper.innerHTML = `
<p>;( Oopsie! Could not load featured projects...</p>
`
throw new Error("Failed to fetch featured projects JSON");
}
const data = await response.json();
data.forEach(project => {
const featuredDiv = document.createElement("div");
featuredDiv.classList.add("featuredProject");
featuredDiv.id = `featured-${project}`;
featuredDiv.innerHTML = `
<a href="project.html?id=${project}">
<img src="projects/${project}/logo.png">
<p>:${project}</p>
</a>
`;
featuredHelper.appendChild(featuredDiv);
loadProject(project, document.querySelector(`featured-${project} p`), undefined, undefined, undefined, document.querySelector(`featured-${project} img`))
});
}
getFeaturedJSON();

View file

@ -1 +1 @@
["aboukkit"]
["aboukkit", "ghostsandstuff"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="project.js"></script>
<script src="featured.js" defer></script>
<title>NBeta</title>
<title>neoBeta</title>
</head>
<body>
<div id="everythingHelper">
@ -18,6 +18,7 @@
<a href="index.html">mods</a> -
<a href="index.html">plugins</a>
</ul>
<p id="credits">Adrian Victor, 2025 (<a href="https://git.disroot.org/adrianvictor/neoBeta">Unlicense</a>)</p>
</div>
</header>
<main>

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css" media="screen">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NBeta</title>
<title>neoBeta</title>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<!-- <script src="MinecraftColorCodes.3.7.js"></script> -->
<script src="project.js"></script>
@ -19,27 +19,33 @@
<a href="index.html">mods</a> -
<a href="index.html">plugins</a>
</ul>
<p id="credits">Adrian Victor, 2025 (<a href="https://git.disroot.org/adrianvictor/neoBeta">Unlicense</a>)</p>
</div>
</header>
<div id="projectHeader">
<img>
<div id="projectTitleSubtitle">
<h1>Loading project...</h1>
<p>...</p>
<div id="projectTitleAuthor">
<h1 id="projectTitle">Loading project...</h1>
<p id="projectAuthor">by tenkuma</p>
</div>
<button>Download</button>
<p id="projectSubtitle">...</p>
</div>
<a id="downloadLink"><button id="downloadButton">Download</button></a>
</div>
<main id="projectDescription">
</main>
</div>
<script>
const downloadButton = document.querySelector("#projectHeader button");
const downloadButton = document.querySelector("#downloadLink");
const header = document.querySelector("#projectHeader");
const headerTitle = document.querySelector("#projectHeader h1");
const subtitle = document.querySelector("#projectHeader p");
const main = document.querySelector("main");
const headerTitle = document.querySelector("#projectTitle");
const subtitle = document.querySelector("#projectSubtitle");
const author = document.querySelector("#projectAuthor");
const logo = document.querySelector("#projectHeader img");
loadProject(projectID, headerTitle, subtitle, main, logo);
const main = document.querySelector("main");
const body = document.querySelector("body");
loadProject(projectID, headerTitle, subtitle, author, main, logo, downloadButton, body, body);
</script>
</body>
</html>

View file

@ -16,16 +16,36 @@ async function getProjectDescription(obj, id = projectID) {
}
}
async function loadProject(id = projectID, objTitle, objSubtitle, objDescription, objLogo) {
async function loadProject(id = projectID, objTitle, objSubtitle, objAuthor, objDescription, objLogo, objDownloadLink, changeColor, changeBackground) {
try {
const jsonData = await getProjectJSON(id);
if (objTitle) objTitle.innerText = jsonData.project.title;
if (objSubtitle) objSubtitle.innerText = jsonData.project.subtitle;
if (objAuthor) objAuthor.innerText = `by ${jsonData.project.author}`;
if (objDescription) await getProjectDescription(objDescription, id);
if (objLogo) objLogo.src = `projects/${id}/logo.png`;
if (jsonData.project.downloadLink) {
if (objDownloadLink) objDownloadLink.href = jsonData.project.downloadLink;
} else {
if (objDownloadLink) objDownloadLink.innerText = "Download unavailable";
}
if (jsonData.project.displayLogo == true) {
if (objLogo) objLogo.src = `projects/${id}/logo.png`;
} else {
objLogo.remove();
}
if (jsonData.project.backgroundColor) {
changeColor.style.backgroundColor = jsonData.project.backgroundColor;
}
if (jsonData.project.backgroundImage) {
changeBackground.style.backgroundImage = `url(${jsonData.project.backgroundImage})`;
}
if (jsonData.project.backgroundImageSize) {
changeBackground.style.backgroundSize = jsonData.project.backgroundImageSize;
}
} catch (error) {
console.error("Error loading project:", error);
}

View file

@ -1,19 +1,20 @@
## Custom commands with predefined responses!
This plugin adds a simple way to add custom commands that will respond users with predefined messages from config.yml. It supports Minecraft's color coding (use & instead of §) and placeholders for player/server info (TODO).
![Aboukkit logo, abboukit written in a Minecraft's logo like font painted in red.](https://cdn.modrinth.com/data/cached_images/94b1f813f8e15f82dddcffa5284c92e59cb93b27.png)
### Default Commands
This plugin adds a simple way to add custom commands that will respond users with predefined messages from ```config.yml```. It supports Minecraft's color coding (use & instead of §) ~~and placeholders for player/server info~~ (TODO).
## Default Commands
- About
- Aboukkit
These default commands §aneed§r to be configured.
### Adding new commands
First of all: run the server with the plugin for the first time, so config.yml is generated.
These default commands need to be configured.
Follow the structure that the template shows in your config.yml. Then use a file explorer to open the plugin's JAR file and edit plugin.yml, you can copy a command entry and fill all the fields (be careful with indentation, YML does not support TAB).
## Adding new commands
First of all: run the server with the plugin for the first time, so ```config.yml``` is generated.
### Why?
Follow the structure that the template shows in your ```config.yml```. Then use a file explorer to open the plugin's JAR file and edit plugin.yml, you can copy a command entry and fill all the fields (be careful with indentation, YML does not support TAB).
## Why?
I made this plugin because I have a server for version b1.7.3 and I wanted to add a /about command to give credit to the server founders and link to our website. So I made this that I will use every time I need a simple 'wall of text' command.
Newer versions
## Newer versions
I don't see why I would build this for latest versions, I guess there are already better solutions. I made this just because of the lack of plugins for Minecraft beta.

View file

@ -1,23 +1,11 @@
{
"project": {
"author": "tenkuma",
"title": "Aboukkit",
"subtitle": "A Brief Subtitle for the Project",
"description": "This is a placeholder description for the project. You can add details about the project's objectives, features, and goals here.",
"logo": "",
"images": [
{
"src": "images/image1.jpg",
"alt": "Image 1 description"
},
{
"src": "images/image2.jpg",
"alt": "Image 2 description"
},
{
"src": "images/image3.jpg",
"alt": "Image 3 description"
}
]
"subtitle": "Adds a simple way to add custom commands with custom responses to your server.",
"downloadLink": "https://modrinth.com/plugin/aboukkit/versions",
"backgroundColor": "darkred",
"displayLogo": true
}
}

View file

@ -0,0 +1,6 @@
This plugins aims to use stuff from my library that would not fit into any plugin (or not in the way presented here) that has ~~a lot~~ (WIP) of random stuff. Everything should be togglable in the config.
## Features
- **RainbowChat:** Rainbow color code.
- **SkibidiBlocker:** Strike a lightning on players that say a word.
- **AntiSpam:** Blocks repeated words in the chat. Optionally can strike a lightning to the player who is spamming.

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

View file

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Before After
Before After

View file

@ -0,0 +1,11 @@
{
"project": {
"author": "tenkuma",
"title": "Ghosts 'n Stuff",
"subtitle": "Adds a simple way to add custom commands with custom responses to your server.",
"backgroundImage": "projects/ghostsandstuff/ghosts.jpg",
"backgroundImageSize": "cover",
"displayLogo": true
}
}

View file

@ -27,7 +27,8 @@ a {
main {
outline: 2px solid gray;
margin-top: 20px;
padding: 10px;
padding: 20px;
background-color: black;
}
button {
@ -35,7 +36,7 @@ button {
background-color: black;
color: white;
padding: 10px;
border: 1px solid white;
outline: 1px white;
}
button:hover {
@ -43,22 +44,15 @@ button:hover {
border: 1px solid gray;
}
/* #titleBox {
background-color: brown;
width: 100px;
height: 100px;
color: white;
text-align: center;
background: url("1.gif");
background-size: contain;
outline: 2px solid white;
margin-right: 12px;
} */
/* #titleBox:hover ~ #linksBox {
outline: 2px solid white;
height: auto;
} */
code {
font-family: Minecraft, 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: rgb(75, 75, 75);
border: 1px solid white;
padding-left: 4px;
padding-right: 4px;
/* margin-left: 2px;
margin-right: 2px; */
}
#linksBox {
padding: 10px;
@ -149,24 +143,31 @@ button:hover {
padding-top: 20px;
gap: 20px;
display: flex;
text-shadow: 2px 2px gray;
}
#projectHeader button {
#downloadButton {
border: 2px solid gray;
}
#downloadLink {
color: gray;
height: fit-content;
margin-top: auto;
margin-bottom: auto;
margin-left: auto;
margin-right: 20px;
text-align: right;
text-shadow: 2px 2px black;
}
#projectHeader button:hover {
#downloadButton:hover {
cursor: pointer;
border-color: white;
}
#projectHeader img {
outline: 2px solid gray;
width: 5vw;
height: 5vw;
height: 100%;
}
#projectDescription li {
@ -175,7 +176,21 @@ button:hover {
}
#projectDescription h1, h2 {
margin-bottom: 8px;
margin-top: 8px;
}
#projectTitleAuthor {
display: flex;
}
#projectAuthor {
margin-left: 10px;
margin-top: auto;
margin-bottom: 6px;
}
#credits {
margin-left: auto;
}
@media only screen and (max-width: 1280px) {
@ -193,6 +208,29 @@ button:hover {
margin-right: auto;
}
#projectHeader {
flex-direction: column;
text-align: center;
}
#projectHeader * {
margin-left: auto;
margin-right: auto;
}
#projectAuthor {
margin-left: 10px;
}
#projectTitle {
margin-right: 0;
}
#projectHeader img {
width: 10vh;
height: 10vh;
}
}
@media only screen and (max-width: 300px) {
@ -201,5 +239,12 @@ button:hover {
max-width: 90%;
}
#projectTitleAuthor {
flex-direction: column;
}
#projectAuthor {
margin: 0;
}
}