Uploaded Source
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2022 LAX1DUDE
|
Copyright (c) 2022 Calder Young
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
41
README.md
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Eaglercraft HTML5 Ping Embed
|
||||||
|
|
||||||
|
### This allows you to easily embed your Eaglercraft server's ping, player list, and MOTD in a \<div\> element in an HTML5 document using the same style as the game's multiplayer screen
|
||||||
|
|
||||||
|
![Eaglercraft HTML5 Ping Embed](https://i.gyazo.com/3db6a206bca69da3545a6083bc8aa7eb.gif)
|
||||||
|
|
||||||
|
### Demo link: [https://g.eags.us/eaglercraft/ping.html](https://g.eags.us/eaglercraft/ping.html)
|
||||||
|
|
||||||
|
# How to install:
|
||||||
|
|
||||||
|
1. Download 'embed.min.js' and 'icons.png' and upload them to your server
|
||||||
|
|
||||||
|
2. Add the script: `<script type="text/javascript" src="embed.min.js"></script>`
|
||||||
|
|
||||||
|
3. Create a \<div\> like: `<div id="embed"></div>`
|
||||||
|
|
||||||
|
4. In your Javascript, create a new `ServerEmbed` object. Pass the \<div\> object and a CSS width as parameters:
|
||||||
|
`var embed = new ServerEmbed(document.getElementById("embed"), "500px");`
|
||||||
|
|
||||||
|
5. Call the `ping` function on the new object: `embed.ping("127.0.0.1:25565");`
|
||||||
|
|
||||||
|
(Replace `127.0.0.1:25565` with the `ip:port` or `ws://` or `wss://` address of your server)
|
||||||
|
|
||||||
|
6. You're done
|
||||||
|
|
||||||
|
## Extra features:
|
||||||
|
|
||||||
|
The `ping` function takes five arguments, four of which are optional:
|
||||||
|
```javascript
|
||||||
|
ping(addr, name, forceName, hideAddress, hideCracked)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `addr` Is the `ip:port` or `ws://` or `wss://` address of your server
|
||||||
|
|
||||||
|
- `name` *(Optional)* Sets the name to display for the server, if left undefined then the default name displayed for the server is the `server_name:` variable of config.yml of the server being pinged (once the server responds)
|
||||||
|
|
||||||
|
- `forceName` *(Optional)* Sets if the `name` parameter should always be shown as the server's name instead of the pinged server's config.yml `server_name:` sent in the response to the ping. Default is false, so by default the optional `name` parameter is only shown until the server responds with it's configured `server_name:`, which is then displayed instead until the ping is sent again
|
||||||
|
|
||||||
|
- `hideAddress` *(Optional)* Sets if the second line of the server's MOTD **should not display** the `addr` parameter on the canvas while it is still connecting, and then also if it shouldn't display the `addr` when the destination server's response does not specify a second line in it's MOTD. Default is false
|
||||||
|
|
||||||
|
- `hideCracked` *(Optional)* Sets if the warning icon and padlock icon, which indicate if the server uses online mode or not, should be hidden from the embed so nobody can tell if your server is cracked or not. Default is false
|
724
embed.js
Normal file
|
@ -0,0 +1,724 @@
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Calder Young
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
const CHAR_WIDTHS = [
|
||||||
|
1,9,9,8,8,8,8,7,9,8,9,9,8,9,9,9,
|
||||||
|
8,8,8,8,9,9,8,9,8,8,8,8,8,9,9,9,
|
||||||
|
4,2,5,6,6,6,6,3,5,5,5,6,2,6,2,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,2,2,5,6,5,6,
|
||||||
|
7,6,6,6,6,6,6,6,6,4,6,6,6,6,6,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,4,6,4,6,6,
|
||||||
|
3,6,6,6,6,6,5,6,6,2,6,5,3,6,6,6,
|
||||||
|
6,6,6,6,4,6,6,6,6,6,6,5,2,5,7,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,4,6,3,6,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,4,6,
|
||||||
|
6,3,6,6,6,6,6,6,6,7,6,6,6,2,6,6,
|
||||||
|
8,9,9,6,6,6,8,8,6,8,8,8,8,8,6,6,
|
||||||
|
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||||
|
9,9,9,9,9,9,9,9,9,6,9,9,9,5,9,9,
|
||||||
|
8,7,7,8,7,8,8,8,7,8,8,7,9,9,6,7,
|
||||||
|
7,7,7,7,9,6,7,8,7,6,6,9,7,6,7,1
|
||||||
|
];
|
||||||
|
|
||||||
|
const CHAR_SHADOW_BRIGHTNESS = 0.247;
|
||||||
|
|
||||||
|
const SERVER_ASPECT_RATIO = 38.0 / 256.0;
|
||||||
|
|
||||||
|
class ServerEmbed {
|
||||||
|
|
||||||
|
constructor(tag, width) {
|
||||||
|
this.containerTag = tag;
|
||||||
|
tag.style.width = width;
|
||||||
|
tag.style.height = Math.floor(tag.clientWidth * SERVER_ASPECT_RATIO) + "px";
|
||||||
|
tag.style.backgroundColor = "black";
|
||||||
|
this.canvas = document.createElement("canvas");
|
||||||
|
this.canvas.width = tag.clientWidth;
|
||||||
|
this.canvas.height = tag.clientHeight;
|
||||||
|
tag.appendChild(this.canvas);
|
||||||
|
this.ctx = this.canvas.getContext("2d");
|
||||||
|
if(!this.ctx) {
|
||||||
|
throw new Error("CanvasRenderingContext2D is not supported in this browser");
|
||||||
|
}
|
||||||
|
this.ctx.imageSmoothingEnabled = false;
|
||||||
|
this.tmpCanvas = document.createElement("canvas");
|
||||||
|
this.tmpCanvas.width = 64;
|
||||||
|
this.tmpCanvas.height = 64;
|
||||||
|
this.tmpCtx = this.tmpCanvas.getContext("2d");
|
||||||
|
this.tmpCtx.imageSmoothingEnabled = false;
|
||||||
|
const self = this;
|
||||||
|
this.spriteSheet = document.createElement("img");
|
||||||
|
this.spriteSheet.addEventListener("load", () => {
|
||||||
|
self.isSpriteSheetLoaded = true;
|
||||||
|
setInterval(() => self.redraw(), 50);
|
||||||
|
});
|
||||||
|
this.spriteSheet.src = "icons.png";
|
||||||
|
this.socket = null;
|
||||||
|
this.connected = false;
|
||||||
|
this.dirty = false;
|
||||||
|
this.connecting = 0;
|
||||||
|
this.currentStatus = {
|
||||||
|
serverName: "",
|
||||||
|
serverCracked: false,
|
||||||
|
pingSentTime: 0,
|
||||||
|
pingToServer: -1,
|
||||||
|
motdLine1: "",
|
||||||
|
motdLine2: "",
|
||||||
|
onlineCount: 0,
|
||||||
|
maxCount: 0,
|
||||||
|
players: []
|
||||||
|
};
|
||||||
|
this.showCracked = true;
|
||||||
|
this.tooltip = "";
|
||||||
|
this.isShowingTooltip = false;
|
||||||
|
this.isTooltipEnabled = true;
|
||||||
|
this.tooltipCanvas = document.createElement("canvas");
|
||||||
|
this.tooltipCanvas.width = 64;
|
||||||
|
this.tooltipCanvas.height = 64;
|
||||||
|
this.tooltipCanvas.style.display = "none";
|
||||||
|
this.tooltipCanvas.style.position = "absolute";
|
||||||
|
this.tooltipCanvas.style.zIndex = "100";
|
||||||
|
this.tooltipCanvas.style.pointerEvents = "none";
|
||||||
|
this.tooltipCtx = this.tooltipCanvas.getContext("2d");
|
||||||
|
this.tooltipCtx.imageSmoothingEnabled = false;
|
||||||
|
document.body.appendChild(this.tooltipCanvas);
|
||||||
|
this.mouseOver = false;
|
||||||
|
this.mouseX = 0;
|
||||||
|
this.mouseY = 0;
|
||||||
|
this.mousePageX = 0;
|
||||||
|
this.mousePageY = 0;
|
||||||
|
var mouseMove = (e) => {
|
||||||
|
self.mouseOver = true;
|
||||||
|
self.mouseX = e.offsetX / self.canvas.width * 256.0;
|
||||||
|
self.mouseY = e.offsetY / self.canvas.height * 38.0;
|
||||||
|
self.mousePageX = e.pageX;
|
||||||
|
self.mousePageY = e.pageY;
|
||||||
|
};
|
||||||
|
this.canvas.addEventListener("mouseover", mouseMove);
|
||||||
|
this.canvas.addEventListener("mousemove", mouseMove);
|
||||||
|
this.canvas.addEventListener("mouseout", (e) => {
|
||||||
|
self.mouseOver = false;
|
||||||
|
self.tooltipCanvas.style.display = "none";
|
||||||
|
});
|
||||||
|
this.lastWidth = 0;
|
||||||
|
this.redrawTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setShowCracked(b) {
|
||||||
|
if(b != this.showCracked) {
|
||||||
|
this.showCracked = b;
|
||||||
|
this.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setShowTooltip(b) {
|
||||||
|
this.isTooltipEnabled = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPixelX(x) {
|
||||||
|
return x * this.canvas.width / 256.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPixelY(y) {
|
||||||
|
return y * this.canvas.height / 38.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawIcon(x, y, w, h, dx, dy, dw, dh) {
|
||||||
|
if(this.isSpriteSheetLoaded) {
|
||||||
|
this.ctx.drawImage(this.spriteSheet, x + 0.05, y + 0.05, w - 0.1, h - 0.1, this.getPixelX(dx),
|
||||||
|
this.getPixelY(dy), this.getPixelX(dw||w), this.getPixelY(dh||h));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawChar(x, y, ch, italic) {
|
||||||
|
if(ch >= CHAR_WIDTHS.length) {
|
||||||
|
ch = 176;
|
||||||
|
}
|
||||||
|
if(!italic) {
|
||||||
|
this.drawIcon(ch % 16 * 8, Math.floor(ch / 16.0) * 8.0, CHAR_WIDTHS[ch], 8, x, y);
|
||||||
|
}else {
|
||||||
|
if(this.isSpriteSheetLoaded) {
|
||||||
|
this.ctx.resetTransform();
|
||||||
|
this.ctx.scale(this.canvas.width / 256.0, this.canvas.height / 38.0);
|
||||||
|
this.ctx.translate(x + 1.1, y);
|
||||||
|
this.ctx.transform(1, 0, -0.35, 1, 0, 0);
|
||||||
|
this.ctx.drawImage(this.spriteSheet, ch % 16 * 8, Math.floor(ch / 16.0) * 8.0,
|
||||||
|
CHAR_WIDTHS[ch] * 0.99, 8 * 0.99, 0, 0, CHAR_WIDTHS[ch], 8);
|
||||||
|
this.ctx.resetTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CHAR_WIDTHS[ch];
|
||||||
|
}
|
||||||
|
|
||||||
|
drawColoredChar(x, y, ch, color, italic) {
|
||||||
|
if(ch >= CHAR_WIDTHS.length) {
|
||||||
|
ch = 176;
|
||||||
|
}
|
||||||
|
if(!this.isSpriteSheetLoaded) {
|
||||||
|
return CHAR_WIDTHS[ch];
|
||||||
|
}
|
||||||
|
this.tmpCtx.globalCompositeOperation = "source-over";
|
||||||
|
this.tmpCtx.clearRect(0, 0, 8, 8);
|
||||||
|
this.tmpCtx.imageSmoothingEnabled = false;
|
||||||
|
this.tmpCtx.drawImage(this.spriteSheet, ch % 16 * 8, Math.floor(ch / 16.0) * 8.0,
|
||||||
|
CHAR_WIDTHS[ch] * 0.99, 8 * 0.99, 0, 0, CHAR_WIDTHS[ch], 8);
|
||||||
|
this.tmpCtx.globalCompositeOperation = "source-in";
|
||||||
|
this.tmpCtx.fillStyle = color;
|
||||||
|
this.tmpCtx.fillRect(0, 0, CHAR_WIDTHS[ch], 8);
|
||||||
|
|
||||||
|
if(!italic) {
|
||||||
|
this.ctx.drawImage(this.tmpCanvas, 0, 0, CHAR_WIDTHS[ch] * 0.99, 8 * 0.99, this.getPixelX(x),
|
||||||
|
this.getPixelY(y), this.getPixelX(CHAR_WIDTHS[ch]), this.getPixelY(8));
|
||||||
|
}else {
|
||||||
|
this.ctx.resetTransform();
|
||||||
|
this.ctx.scale(this.canvas.width / 256.0, this.canvas.height / 38.0);
|
||||||
|
this.ctx.translate(x + 1.1, y);
|
||||||
|
this.ctx.transform(1, 0, -0.35, 1, 0, 0);
|
||||||
|
this.ctx.drawImage(this.tmpCanvas, 0, 0, CHAR_WIDTHS[ch] * 0.99, 8 * 0.99, 0, 0, CHAR_WIDTHS[ch], 8);
|
||||||
|
this.ctx.resetTransform();
|
||||||
|
}
|
||||||
|
return CHAR_WIDTHS[ch];
|
||||||
|
}
|
||||||
|
|
||||||
|
drawCharLine(x, y, w, clr) {
|
||||||
|
this.ctx.fillStyle = clr;
|
||||||
|
this.ctx.fillRect(this.getPixelX(x), this.getPixelY(y), this.getPixelX(w + 0.02), this.getPixelY(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
makeColor(r, g, b) {
|
||||||
|
return "rgba(" + Math.floor(r) + "," + Math.floor(g) + "," + Math.floor(b) + ",1.0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
getStringWidth(txt, escapeChar) {
|
||||||
|
if(!escapeChar) {
|
||||||
|
escapeChar = 167;
|
||||||
|
}else {
|
||||||
|
escapeChar = escapeChar.charCodeAt(0);
|
||||||
|
}
|
||||||
|
var j = 0;
|
||||||
|
for(var i = 0; i < txt.length; ++i) {
|
||||||
|
var c = txt.charCodeAt(i);
|
||||||
|
if(c == escapeChar) {
|
||||||
|
i += 2;
|
||||||
|
}else {
|
||||||
|
if(c < CHAR_WIDTHS.length) {
|
||||||
|
j += CHAR_WIDTHS[c];
|
||||||
|
}else {
|
||||||
|
j += 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawString(x, y, txt, r, g, b, shadow, randomSeed, escapeChar) {
|
||||||
|
var escapeCharChar = escapeChar;
|
||||||
|
if(!escapeChar) {
|
||||||
|
escapeChar = 167;
|
||||||
|
}else {
|
||||||
|
escapeChar = escapeChar.charCodeAt(0);
|
||||||
|
}
|
||||||
|
var startX = x;
|
||||||
|
var startY = y;
|
||||||
|
if(shadow) {
|
||||||
|
++x;
|
||||||
|
++y;
|
||||||
|
}
|
||||||
|
if(!randomSeed) {
|
||||||
|
randomSeed = 3492589035;
|
||||||
|
}
|
||||||
|
var readFormat = false;
|
||||||
|
var cr = r;
|
||||||
|
var cg = g;
|
||||||
|
var cb = b;
|
||||||
|
var obfuscate = false; var bold = false; var strikethrough = false;
|
||||||
|
var underline = false; var italic = false;
|
||||||
|
for(var i = 0; i < txt.length; ++i) {
|
||||||
|
var c = txt.charCodeAt(i);
|
||||||
|
if(c == escapeChar) { // color code symbol
|
||||||
|
readFormat = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(readFormat) {
|
||||||
|
if(c == 48) { // black (0)
|
||||||
|
cr = cg = cb = 0;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 49) { // dark_blue (1)
|
||||||
|
cr = cg = 0;
|
||||||
|
cb = 170;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 50) { // dark_green (2)
|
||||||
|
cr = cb = 0;
|
||||||
|
cg = 170;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 51) { // dark_aqua (3)
|
||||||
|
cr = 0;
|
||||||
|
cg = cb = 170;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 52) { // dark_red (4)
|
||||||
|
cr = 170;
|
||||||
|
cg = cb = 0;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 53) { // dark_purple (5)
|
||||||
|
cr = cb = 170;
|
||||||
|
cg = 0;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 54) { // gold (6)
|
||||||
|
cr = 255;
|
||||||
|
cg = 170;
|
||||||
|
cb = 0;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 55) { // gray (7)
|
||||||
|
cr = cg = cb = 170;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 56) { // dark_gray (8)
|
||||||
|
cr = cg = cb = 85;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 57) { // blue (9)
|
||||||
|
cr = cg = 85;
|
||||||
|
cb = 255;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 97) { // green (a)
|
||||||
|
cr = cb = 85;
|
||||||
|
cg = 255;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 98) { // aqua (b)
|
||||||
|
cr = 85;
|
||||||
|
cg = cb = 255;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 99) { // red (c)
|
||||||
|
cg = cb = 85;
|
||||||
|
cr = 255;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 100) { // light_purple (d)
|
||||||
|
cr = cb = 255;
|
||||||
|
cg = 85;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 101) { // yellow (e)
|
||||||
|
cr = cg = 255;
|
||||||
|
cb = 85;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 102) { // white (f)
|
||||||
|
cr = cg = cb = 255;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}else if(c == 107) { // obfuscated (k)
|
||||||
|
readFormat = false;
|
||||||
|
obfuscate = true;
|
||||||
|
continue;
|
||||||
|
}else if(c == 108) { // bold (l)
|
||||||
|
readFormat = false;
|
||||||
|
bold = true;
|
||||||
|
continue;
|
||||||
|
}else if(c == 109) { // strikethrough (m)
|
||||||
|
readFormat = false;
|
||||||
|
strikethrough = true;
|
||||||
|
continue;
|
||||||
|
}else if(c == 110) { // underline (n)
|
||||||
|
readFormat = false;
|
||||||
|
underline = true;
|
||||||
|
continue;
|
||||||
|
}else if(c == 111) { // italic (o)
|
||||||
|
readFormat = false;
|
||||||
|
italic = true;
|
||||||
|
continue;
|
||||||
|
}else if(c == 114) { // reset (r)
|
||||||
|
cr = r;
|
||||||
|
cg = g;
|
||||||
|
cb = b;
|
||||||
|
readFormat = obfuscate = bold =
|
||||||
|
strikethrough = underline = italic = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
readFormat = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(obfuscate) {
|
||||||
|
this.dirty = true;
|
||||||
|
var w = 6
|
||||||
|
if(c < CHAR_WIDTHS.length) {
|
||||||
|
w = CHAR_WIDTHS[c];
|
||||||
|
}
|
||||||
|
var j = 0;
|
||||||
|
var newChar = 0;
|
||||||
|
do {
|
||||||
|
var t = randomSeed += 0x6D2B79F5;
|
||||||
|
t = Math.imul(t ^ t >>> 15, t | 1);
|
||||||
|
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
||||||
|
newChar = (((t ^ t >>> 14) >>> 0) / 429496) & 255;
|
||||||
|
}while((newChar == c || CHAR_WIDTHS[newChar] != w) && ++j < 1000);
|
||||||
|
c = newChar;
|
||||||
|
}
|
||||||
|
if(shadow) {
|
||||||
|
var ccc = this.makeColor(cr * CHAR_SHADOW_BRIGHTNESS,
|
||||||
|
cg * CHAR_SHADOW_BRIGHTNESS, cb * CHAR_SHADOW_BRIGHTNESS);
|
||||||
|
var ox = x;
|
||||||
|
var ow = 0;
|
||||||
|
if(bold) this.drawColoredChar(x + 1, y + 1, c, ccc, italic);
|
||||||
|
x += (ow = this.drawColoredChar(x, y, c, ccc, italic));
|
||||||
|
if(bold) {
|
||||||
|
++x;
|
||||||
|
++ow;
|
||||||
|
}
|
||||||
|
if(strikethrough) this.drawCharLine(ox, y + 4, ow, ccc);
|
||||||
|
if(underline) this.drawCharLine(ox, y + 8, ow, ccc);
|
||||||
|
}else {
|
||||||
|
if(cr >= 250 && cg >= 250 && cb >= 250) {
|
||||||
|
var ox = x;
|
||||||
|
var ow = 0;
|
||||||
|
if(bold) this.drawChar(x + 0.5, y + 0.5, c, italic);
|
||||||
|
x += (ow = this.drawChar(x, y, c, italic));
|
||||||
|
if(bold) {
|
||||||
|
++x;
|
||||||
|
++ow;
|
||||||
|
}
|
||||||
|
if(strikethrough) this.drawCharLine(ox, y + 4, ow, "#FFFFFF");
|
||||||
|
if(underline) this.drawCharLine(ox, y + 8, ow, "#FFFFFF");
|
||||||
|
}else {
|
||||||
|
var ccc = this.makeColor(cr,cg,cb);
|
||||||
|
var ox = x;
|
||||||
|
var ow = 0;
|
||||||
|
if(bold) this.drawColoredChar(x + 0.5, y + 0.5, c, ccc, italic);
|
||||||
|
x += (ow = this.drawColoredChar(x, y, c, ccc, italic));
|
||||||
|
if(bold) {
|
||||||
|
++x;
|
||||||
|
++ow;
|
||||||
|
}
|
||||||
|
if(strikethrough) this.drawCharLine(ox, y + 4, ow, ccc);
|
||||||
|
if(underline) this.drawCharLine(ox, y + 8, ow, ccc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(x > 250.0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(shadow) {
|
||||||
|
this.drawString(startX, startY, txt, r, g, b, false, randomSeed, escapeCharChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redraw() {
|
||||||
|
if(this.dirty || (this.mouseOver && ++this.redrawTimer % 6 == 0) || this.canvas.width != this.containerTag.clientWidth) {
|
||||||
|
this.dirty = false;
|
||||||
|
if(this.canvas.width != this.containerTag.clientWidth) {
|
||||||
|
this.containerTag.style.height = Math.floor(this.containerTag.clientWidth * SERVER_ASPECT_RATIO) + "px";
|
||||||
|
this.canvas.width = this.containerTag.clientWidth;
|
||||||
|
this.canvas.height = this.containerTag.clientHeight;
|
||||||
|
}
|
||||||
|
var tooltipNewArray = [];
|
||||||
|
this.ctx.imageSmoothingEnabled = false;
|
||||||
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||||
|
this.ctx.fillStyle = "#101010";
|
||||||
|
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
||||||
|
this.ctx.strokeStyle = "#808080";
|
||||||
|
this.ctx.lineWidth = this.getPixelX(1.0);
|
||||||
|
this.ctx.strokeRect(this.ctx.lineWidth / 2, this.ctx.lineWidth / 2,this.canvas.width - this.ctx.lineWidth,this.canvas.height - this.ctx.lineWidth);
|
||||||
|
|
||||||
|
if(!this.iconCanvas) {
|
||||||
|
this.drawIcon(128, 0, 64, 64, 4, 4, 30, 30);
|
||||||
|
}else {
|
||||||
|
this.ctx.drawImage(this.iconCanvas, 0, 0, 64, 64, this.getPixelX(4),
|
||||||
|
this.getPixelY(4), this.getPixelX(30), this.getPixelY(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
var v = Date.now();
|
||||||
|
var drawAddress = false;
|
||||||
|
|
||||||
|
this.drawString(38, 4, this.currentStatus.serverName, 255, 255, 255, true, v);
|
||||||
|
if(this.currentStatus.pingToServer >= 0) {
|
||||||
|
if(this.currentStatus.motdLine1.length > 0) {
|
||||||
|
this.drawString(38, 15, ""+this.currentStatus.motdLine1, 255, 255, 255, true, v);
|
||||||
|
}
|
||||||
|
if(this.currentStatus.motdLine2.length > 0) {
|
||||||
|
this.drawString(38, 27, ""+this.currentStatus.motdLine2, 255, 255, 255, true, v);
|
||||||
|
}else {
|
||||||
|
drawAddress = true;
|
||||||
|
}
|
||||||
|
}else if(v - this.connecting < 7000) {
|
||||||
|
this.dirty = true;
|
||||||
|
var dots = Math.floor(v / 300) % 4;
|
||||||
|
this.drawString(38, 15, "Connecting" + (dots > 0 ? "." : "") + (dots > 1 ? "." : "") + (dots > 2 ? "." : ""), 128, 128, 128, true, v);
|
||||||
|
drawAddress = true;
|
||||||
|
}else {
|
||||||
|
this.drawString(38, 15, "No Connection", 96, 96, 96, true, v);
|
||||||
|
drawAddress = true;
|
||||||
|
}
|
||||||
|
if(drawAddress && this.showAddress) {
|
||||||
|
this.drawString(38, 27, this.originalAddress, 48, 48, 48, true, v);
|
||||||
|
}
|
||||||
|
var mouseIsOverPing = this.mouseOver && this.mouseX >= 233 && this.mouseX <= 256 && this.mouseY >= 1 && this.mouseY <= 11;
|
||||||
|
var mouseIsOverPlayers = false;
|
||||||
|
if(this.currentStatus.pingToServer >= 0) {
|
||||||
|
if(mouseIsOverPing) tooltipNewArray = [""+this.currentStatus.pingToServer+"ms"];
|
||||||
|
var i = 5;
|
||||||
|
if(this.currentStatus.pingToServer < 150) i = 0;
|
||||||
|
else if(this.currentStatus.pingToServer < 300) i = 1;
|
||||||
|
else if(this.currentStatus.pingToServer < 600) i = 2;
|
||||||
|
else if(this.currentStatus.pingToServer < 1000) i = 3;
|
||||||
|
else i = 4;
|
||||||
|
this.drawIcon(128, 80 + i * 8, 10, 7, 243, 3);
|
||||||
|
var onlineStr = "" + this.currentStatus.onlineCount + "/" + this.currentStatus.maxCount;
|
||||||
|
var xx = 253 - this.getStringWidth(onlineStr);
|
||||||
|
mouseIsOverPlayers = !mouseIsOverPing && this.mouseOver && this.mouseX >= xx - 5 && this.mouseX <= 256
|
||||||
|
&& this.mouseY >= 12 && this.mouseY <= 23;
|
||||||
|
this.drawString(xx, 14, onlineStr, 128, 128, 128, true);
|
||||||
|
if(mouseIsOverPlayers) {
|
||||||
|
tooltipNewArray = this.currentStatus.players;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if(v - this.connecting < 7000 || this.connected) {
|
||||||
|
this.dirty = true;
|
||||||
|
if(mouseIsOverPing) tooltipNewArray = ["Connecting..."];
|
||||||
|
this.drawIcon(138, 80 + Math.abs(Math.floor(v / 100.0) % 8 - 4) * 8, 10, 7, 243, 3);
|
||||||
|
}else {
|
||||||
|
if(mouseIsOverPing) tooltipNewArray = ["No Connection"];
|
||||||
|
this.drawIcon(128, 120, 10, 7, 243, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(this.showCracked && this.currentStatus.pingToServer >= 0) {
|
||||||
|
if(this.currentStatus.serverCracked) {
|
||||||
|
this.drawIcon(144, 64, 16, 16, 243, 25, 10, 10);
|
||||||
|
}else {
|
||||||
|
this.drawIcon(176, 96, 16, 16, 243, 25, 11, 11);
|
||||||
|
}
|
||||||
|
if(!mouseIsOverPlayers && this.mouseOver && this.mouseX >= 239 && this.mouseX <= 256
|
||||||
|
&& this.mouseY >= 22 && this.mouseY <= 36) {
|
||||||
|
if(this.currentStatus.serverCracked) {
|
||||||
|
tooltipNewArray = ["Server is cracked"];
|
||||||
|
}else {
|
||||||
|
tooltipNewArray = ["Server has login"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!tooltipNewArray || !this.mouseOver || tooltipNewArray.length == 0) {
|
||||||
|
this.tooltipCanvas.style.display = "none";
|
||||||
|
}else {
|
||||||
|
this.showTooltip(tooltipNewArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ping(addr, name, forceName, hideAddress, hideCracked) {
|
||||||
|
if(!name) {
|
||||||
|
name = "Minecraft Server";
|
||||||
|
this.showQueryName = (typeof forceName === "undefined") || !forceName;
|
||||||
|
}else {
|
||||||
|
this.showQueryName = (typeof forceName !== "undefined") && !forceName;
|
||||||
|
}
|
||||||
|
this.defaultName = name;
|
||||||
|
this.showAddress = !hideAddress;
|
||||||
|
this.originalAddress = addr;
|
||||||
|
if(typeof hideCracked !== "undefined") {
|
||||||
|
this.showCracked = !hideCracked;
|
||||||
|
}
|
||||||
|
if(addr.indexOf("ws://") != 0 && addr.indexOf("wss://") != 0) {
|
||||||
|
addr = (window.location.href.indexOf("https:") == 0 ? "wss" : "ws") + "://" + addr;
|
||||||
|
}
|
||||||
|
if(this.socket != null && this.connected) {
|
||||||
|
this.socket.close();
|
||||||
|
}
|
||||||
|
this.currentStatus = {
|
||||||
|
serverName: name,
|
||||||
|
serverCracked: false,
|
||||||
|
pingSentTime: Date.now(),
|
||||||
|
pingToServer: -1,
|
||||||
|
motdLine1: "Connecting...",
|
||||||
|
motdLine2: "",
|
||||||
|
onlineCount: 0,
|
||||||
|
maxCount: 0,
|
||||||
|
players: []
|
||||||
|
};
|
||||||
|
this.dirty = true;
|
||||||
|
if(this.connected || this.connecting > 0) {
|
||||||
|
this.socket.close();
|
||||||
|
this.connected = false;
|
||||||
|
this.connecting = 0;
|
||||||
|
this.redraw();
|
||||||
|
}
|
||||||
|
this.connecting = Date.now();
|
||||||
|
const self = this;
|
||||||
|
this.socket = new WebSocket(addr);
|
||||||
|
this.socket.binaryType = "arraybuffer";
|
||||||
|
this.socket.onopen = () => {
|
||||||
|
self.socket.send("Accept: MOTD");
|
||||||
|
self.connecting = 0;
|
||||||
|
self.connected = true;
|
||||||
|
self.dirty = true;
|
||||||
|
};
|
||||||
|
this.socket.onmessage = (e) => {
|
||||||
|
if(e.data) {
|
||||||
|
if(typeof e.data === "string") {
|
||||||
|
try {
|
||||||
|
var dat = JSON.parse(e.data);
|
||||||
|
if(dat["type"].toLowerCase() === "motd") {
|
||||||
|
self.dirty = true;
|
||||||
|
if(self.currentStatus.pingSentTime > 0) {
|
||||||
|
self.currentStatus.pingToServer = Date.now() - self.currentStatus.pingSentTime;
|
||||||
|
self.currentStatus.pingSentTime = 0;
|
||||||
|
}
|
||||||
|
if(this.showQueryName) {
|
||||||
|
self.currentStatus.serverName = dat["name"];
|
||||||
|
}else {
|
||||||
|
self.currentStatus.serverName = this.defaultName;
|
||||||
|
}
|
||||||
|
self.currentStatus.serverCracked = dat["cracked"];
|
||||||
|
var lns = dat["data"]["motd"];
|
||||||
|
if(lns && lns.length > 0) {
|
||||||
|
self.currentStatus.motdLine1 = lns[0];
|
||||||
|
if(lns.length > 1) {
|
||||||
|
self.currentStatus.motdLine2 = lns[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.currentStatus.onlineCount = dat["data"]["online"];
|
||||||
|
self.currentStatus.maxCount = dat["data"]["max"];
|
||||||
|
self.currentStatus.players = dat["data"]["players"]||[];
|
||||||
|
}
|
||||||
|
}catch(e) {
|
||||||
|
self.currentStatus.motdLine1 = "ERROR: " + e;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
var dat = new Uint8Array(e.data);
|
||||||
|
if(dat.length == 64*64*4) {
|
||||||
|
this.updateIconFromBytes(dat);
|
||||||
|
this.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.socket.onclose = (e) => {
|
||||||
|
self.connecting = 0;
|
||||||
|
self.connected = false;
|
||||||
|
self.dirty = true;
|
||||||
|
};
|
||||||
|
this.socket.onerror = (e) => {
|
||||||
|
if(self.connected || self.connecting > 0) {
|
||||||
|
self.socket.close();
|
||||||
|
}
|
||||||
|
self.connecting = 0;
|
||||||
|
self.connected = false;
|
||||||
|
self.dirty = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
isActive() {
|
||||||
|
return self.connecting > 0 || self.connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTooltip(ttList) {
|
||||||
|
if(this.isTooltipEnabled) {
|
||||||
|
var tst = ttList.join();
|
||||||
|
if(tst !== this.tooltip || this.lastWidth !== this.canvas.width) {
|
||||||
|
var listWidth = 0;
|
||||||
|
var listHeight = ttList.length * 9;
|
||||||
|
for(var i = 0; i < ttList.length; ++i) {
|
||||||
|
listWidth = Math.max(listWidth, this.getStringWidth(ttList[i]));
|
||||||
|
}
|
||||||
|
listWidth += 6;
|
||||||
|
listHeight += 3;
|
||||||
|
this.tooltipCanvas.width = this.getPixelX(listWidth);
|
||||||
|
this.tooltipCanvas.height = this.getPixelY(listHeight);
|
||||||
|
var mainCtx = this.ctx;
|
||||||
|
this.ctx = this.tooltipCtx;
|
||||||
|
this.ctx.imageSmoothingEnabled = false;
|
||||||
|
this.ctx.clearRect(0, 0, this.tooltipCanvas.width, this.tooltipCanvas.height);
|
||||||
|
this.ctx.fillStyle = "#101010E0";
|
||||||
|
this.ctx.fillRect(0, 0, this.tooltipCanvas.width, this.tooltipCanvas.height);
|
||||||
|
for(var i = 0; i < ttList.length; ++i) {
|
||||||
|
this.drawString(3, (2 + i*9), ttList[i], 256, 256, 256, true);
|
||||||
|
}
|
||||||
|
this.ctx = mainCtx;
|
||||||
|
this.tooltip = tst;
|
||||||
|
this.lastWidth = this.canvas.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showTooltip(ttList) {
|
||||||
|
this.dirty = true;
|
||||||
|
if(!this.mouseOver) {
|
||||||
|
this.tooltipCanvas.style.display = "none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setTooltip(ttList);
|
||||||
|
this.tooltipCanvas.style.display = "block";
|
||||||
|
var x = this.mousePageX + this.getPixelX(4);
|
||||||
|
var y = this.mousePageY - this.getPixelY(9);
|
||||||
|
if(this.mousePageX + this.tooltipCanvas.width + 2 > window.innerWidth) {
|
||||||
|
x = window.innerWidth - this.tooltipCanvas.width - 2;
|
||||||
|
}
|
||||||
|
if(this.mousePageY + this.tooltipCanvas.height + 2 > window.innerHeight) {
|
||||||
|
y = window.innerHeight - this.tooltipCanvas.height - 2;
|
||||||
|
if(y < 0) {
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tooltipCanvas.style.left = x + "px";
|
||||||
|
this.tooltipCanvas.style.top = y + "px";
|
||||||
|
}
|
||||||
|
|
||||||
|
updateIconFromBytes(arr) {
|
||||||
|
if(!this.iconCanvas) {
|
||||||
|
this.iconCanvas = document.createElement("canvas");
|
||||||
|
this.iconCanvas.width = 64;
|
||||||
|
this.iconCanvas.height = 64;
|
||||||
|
this.iconContext = this.iconCanvas.getContext("2d");
|
||||||
|
}
|
||||||
|
var dat = this.iconContext.createImageData(64, 64);
|
||||||
|
for(var i = 0, l = 64*64*4; i < l; ++i) {
|
||||||
|
dat.data[i] = arr[i];
|
||||||
|
}
|
||||||
|
this.iconContext.putImageData(dat, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
30
embed.min.js
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright (c) 2022 Calder Young
|
||||||
|
var CHAR_WIDTHS=[1,9,9,8,8,8,8,7,9,8,9,9,8,9,9,9,8,8,8,8,9,9,8,9,8,8,8,8,8,9,9,9,4,2,5,6,6,6,6,3,5,5,5,6,2,6,2,6,6,6,6,6,6,6,6,6,6,6,2,2,5,6,5,6,7,6,6,6,6,6,6,6,6,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,4,6,4,6,6,3,6,6,6,6,6,5,6,6,2,6,5,3,6,6,6,6,6,6,6,4,6,6,6,6,6,6,5,2,5,7,6,6,6,6,6,6,6,6,6,6,6,6,4,6,3,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,4,6,6,3,6,6,6,6,6,6,6,7,6,6,6,2,6,6,8,9,9,6,6,6,8,8,6,8,8,8,8,8,6,6,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,6,9,9,9,5,9,9,8,7,7,8,7,8,8,8,7,8,8,7,9,9,6,7,7,7,
|
||||||
|
7,7,9,6,7,8,7,6,6,9,7,6,7,1],CHAR_SHADOW_BRIGHTNESS=.247,SERVER_ASPECT_RATIO=.1484375,ServerEmbed=function(a,c){this.containerTag=a;a.style.width=c;a.style.height=Math.floor(a.clientWidth*SERVER_ASPECT_RATIO)+"px";a.style.backgroundColor="black";this.canvas=document.createElement("canvas");this.canvas.width=a.clientWidth;this.canvas.height=a.clientHeight;a.appendChild(this.canvas);this.ctx=this.canvas.getContext("2d");if(!this.ctx)throw Error("CanvasRenderingContext2D is not supported in this browser");
|
||||||
|
this.ctx.imageSmoothingEnabled=!1;this.tmpCanvas=document.createElement("canvas");this.tmpCanvas.width=64;this.tmpCanvas.height=64;this.tmpCtx=this.tmpCanvas.getContext("2d");this.tmpCtx.imageSmoothingEnabled=!1;var b=this;this.spriteSheet=document.createElement("img");this.spriteSheet.addEventListener("load",function(){b.isSpriteSheetLoaded=!0;setInterval(function(){return b.redraw()},50)});this.spriteSheet.src="icons.png";this.socket=null;this.dirty=this.connected=!1;this.connecting=0;this.currentStatus=
|
||||||
|
{serverName:"",serverCracked:!1,pingSentTime:0,pingToServer:-1,motdLine1:"",motdLine2:"",onlineCount:0,maxCount:0,players:[]};this.showCracked=!0;this.tooltip="";this.isShowingTooltip=!1;this.isTooltipEnabled=!0;this.tooltipCanvas=document.createElement("canvas");this.tooltipCanvas.width=64;this.tooltipCanvas.height=64;this.tooltipCanvas.style.display="none";this.tooltipCanvas.style.position="absolute";this.tooltipCanvas.style.zIndex="100";this.tooltipCanvas.style.pointerEvents="none";this.tooltipCtx=
|
||||||
|
this.tooltipCanvas.getContext("2d");this.tooltipCtx.imageSmoothingEnabled=!1;document.body.appendChild(this.tooltipCanvas);this.mouseOver=!1;this.mousePageY=this.mousePageX=this.mouseY=this.mouseX=0;var g=function(e){b.mouseOver=!0;b.mouseX=e.offsetX/b.canvas.width*256;b.mouseY=e.offsetY/b.canvas.height*38;b.mousePageX=e.pageX;b.mousePageY=e.pageY};this.canvas.addEventListener("mouseover",g);this.canvas.addEventListener("mousemove",g);this.canvas.addEventListener("mouseout",function(e){b.mouseOver=
|
||||||
|
!1;b.tooltipCanvas.style.display="none"});this.redrawTimer=this.lastWidth=0};ServerEmbed.prototype.setShowCracked=function(a){a!=this.showCracked&&(this.showCracked=a,this.dirty=!0)};ServerEmbed.prototype.setShowTooltip=function(a){this.isTooltipEnabled=a};ServerEmbed.prototype.getPixelX=function(a){return a*this.canvas.width/256};ServerEmbed.prototype.getPixelY=function(a){return a*this.canvas.height/38};
|
||||||
|
ServerEmbed.prototype.drawIcon=function(a,c,b,g,e,y,f,w){this.isSpriteSheetLoaded&&this.ctx.drawImage(this.spriteSheet,a+.05,c+.05,b-.1,g-.1,this.getPixelX(e),this.getPixelY(y),this.getPixelX(f||b),this.getPixelY(w||g))};
|
||||||
|
ServerEmbed.prototype.drawChar=function(a,c,b,g){b>=CHAR_WIDTHS.length&&(b=176);g?this.isSpriteSheetLoaded&&(this.ctx.resetTransform(),this.ctx.scale(this.canvas.width/256,this.canvas.height/38),this.ctx.translate(a+1.1,c),this.ctx.transform(1,0,-.35,1,0,0),this.ctx.drawImage(this.spriteSheet,b%16*8,8*Math.floor(b/16),.99*CHAR_WIDTHS[b],7.92,0,0,CHAR_WIDTHS[b],8),this.ctx.resetTransform()):this.drawIcon(b%16*8,8*Math.floor(b/16),CHAR_WIDTHS[b],8,a,c);return CHAR_WIDTHS[b]};
|
||||||
|
ServerEmbed.prototype.drawColoredChar=function(a,c,b,g,e){b>=CHAR_WIDTHS.length&&(b=176);if(!this.isSpriteSheetLoaded)return CHAR_WIDTHS[b];this.tmpCtx.globalCompositeOperation="source-over";this.tmpCtx.clearRect(0,0,8,8);this.tmpCtx.imageSmoothingEnabled=!1;this.tmpCtx.drawImage(this.spriteSheet,b%16*8,8*Math.floor(b/16),.99*CHAR_WIDTHS[b],7.92,0,0,CHAR_WIDTHS[b],8);this.tmpCtx.globalCompositeOperation="source-in";this.tmpCtx.fillStyle=g;this.tmpCtx.fillRect(0,0,CHAR_WIDTHS[b],8);e?(this.ctx.resetTransform(),
|
||||||
|
this.ctx.scale(this.canvas.width/256,this.canvas.height/38),this.ctx.translate(a+1.1,c),this.ctx.transform(1,0,-.35,1,0,0),this.ctx.drawImage(this.tmpCanvas,0,0,.99*CHAR_WIDTHS[b],7.92,0,0,CHAR_WIDTHS[b],8),this.ctx.resetTransform()):this.ctx.drawImage(this.tmpCanvas,0,0,.99*CHAR_WIDTHS[b],7.92,this.getPixelX(a),this.getPixelY(c),this.getPixelX(CHAR_WIDTHS[b]),this.getPixelY(8));return CHAR_WIDTHS[b]};
|
||||||
|
ServerEmbed.prototype.drawCharLine=function(a,c,b,g){this.ctx.fillStyle=g;this.ctx.fillRect(this.getPixelX(a),this.getPixelY(c),this.getPixelX(b+.02),this.getPixelY(1))};ServerEmbed.prototype.makeColor=function(a,c,b){return"rgba("+Math.floor(a)+","+Math.floor(c)+","+Math.floor(b)+",1.0)"};ServerEmbed.prototype.getStringWidth=function(a,c){c=c?c.charCodeAt(0):167;for(var b=0,g=0;g<a.length;++g){var e=a.charCodeAt(g);e==c?g+=2:b=e<CHAR_WIDTHS.length?b+CHAR_WIDTHS[e]:b+6}return b};
|
||||||
|
ServerEmbed.prototype.drawString=function(a,c,b,g,e,y,f,w,u){var A=u;u=u?u.charCodeAt(0):167;var B=a,D=c;f&&(++a,++c);w||(w=3492589035);for(var h=!1,p=g,q=e,r=y,t=!1,k=!1,m=!1,n=!1,l=!1,C=0;C<b.length;++C){var d=b.charCodeAt(C);if(d==u)h=!0;else if(h)48==d?(p=q=r=0,h=t=k=m=n=l=!1):49==d?(p=q=0,r=170,h=t=k=m=n=l=!1):50==d?(p=r=0,q=170,h=t=k=m=n=l=!1):51==d?(p=0,q=r=170,h=t=k=m=n=l=!1):52==d?(p=170,q=r=0,h=t=k=m=n=l=!1):53==d?(p=r=170,q=0,h=t=k=m=n=l=!1):54==d?(p=255,q=170,r=0,h=t=k=m=n=l=!1):55==d?
|
||||||
|
(p=q=r=170,h=t=k=m=n=l=!1):56==d?(p=q=r=85,h=t=k=m=n=l=!1):57==d?(p=q=85,r=255,h=t=k=m=n=l=!1):97==d?(p=r=85,q=255,h=t=k=m=n=l=!1):98==d?(p=85,q=r=255,h=t=k=m=n=l=!1):99==d?(q=r=85,p=255,h=t=k=m=n=l=!1):100==d?(p=r=255,q=85,h=t=k=m=n=l=!1):101==d?(p=q=255,r=85,h=t=k=m=n=l=!1):102==d?(p=q=r=255,h=t=k=m=n=l=!1):107==d?(h=!1,t=!0):108==d?(h=!1,k=!0):109==d?(h=!1,m=!0):110==d?(h=!1,n=!0):111==d?(h=!1,l=!0):114==d?(p=g,q=e,r=y,h=t=k=m=n=l=!1):h=!1;else{if(t){this.dirty=!0;var x=6;d<CHAR_WIDTHS.length&&
|
||||||
|
(x=CHAR_WIDTHS[d]);var z=0;do{var v=w+=1831565813;v=Math.imul(v^v>>>15,v|1);v^=v+Math.imul(v^v>>>7,v|61);v=((v^v>>>14)>>>0)/429496&255}while((v==d||CHAR_WIDTHS[v]!=x)&&1E3>++z);d=v}f?(x=this.makeColor(p*CHAR_SHADOW_BRIGHTNESS,q*CHAR_SHADOW_BRIGHTNESS,r*CHAR_SHADOW_BRIGHTNESS),z=a,k&&this.drawColoredChar(a+1,c+1,d,x,l),a+=d=this.drawColoredChar(a,c,d,x,l),k&&(++a,++d),m&&this.drawCharLine(z,c+4,d,x),n&&this.drawCharLine(z,c+8,d,x)):250<=p&&250<=q&&250<=r?(z=a,k&&this.drawChar(a+.5,c+.5,d,l),a+=d=this.drawChar(a,
|
||||||
|
c,d,l),k&&(++a,++d),m&&this.drawCharLine(z,c+4,d,"#FFFFFF"),n&&this.drawCharLine(z,c+8,d,"#FFFFFF")):(x=this.makeColor(p,q,r),z=a,k&&this.drawColoredChar(a+.5,c+.5,d,x,l),a+=d=this.drawColoredChar(a,c,d,x,l),k&&(++a,++d),m&&this.drawCharLine(z,c+4,d,x),n&&this.drawCharLine(z,c+8,d,x));if(250<a)break}}f&&this.drawString(B,D,b,g,e,y,!1,w,A)};
|
||||||
|
ServerEmbed.prototype.redraw=function(){if(this.dirty||this.mouseOver&&0==++this.redrawTimer%6||this.canvas.width!=this.containerTag.clientWidth){this.dirty=!1;this.canvas.width!=this.containerTag.clientWidth&&(this.containerTag.style.height=Math.floor(this.containerTag.clientWidth*SERVER_ASPECT_RATIO)+"px",this.canvas.width=this.containerTag.clientWidth,this.canvas.height=this.containerTag.clientHeight);var a=[];this.ctx.imageSmoothingEnabled=!1;this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);this.ctx.fillStyle=
|
||||||
|
"#101010";this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height);this.ctx.strokeStyle="#808080";this.ctx.lineWidth=this.getPixelX(1);this.ctx.strokeRect(this.ctx.lineWidth/2,this.ctx.lineWidth/2,this.canvas.width-this.ctx.lineWidth,this.canvas.height-this.ctx.lineWidth);this.iconCanvas?this.ctx.drawImage(this.iconCanvas,0,0,64,64,this.getPixelX(4),this.getPixelY(4),this.getPixelX(30),this.getPixelY(30)):this.drawIcon(128,0,64,64,4,4,30,30);var c=Date.now(),b=!1;this.drawString(38,4,this.currentStatus.serverName,
|
||||||
|
255,255,255,!0,c);0<=this.currentStatus.pingToServer?(0<this.currentStatus.motdLine1.length&&this.drawString(38,15,""+this.currentStatus.motdLine1,255,255,255,!0,c),0<this.currentStatus.motdLine2.length?this.drawString(38,27,""+this.currentStatus.motdLine2,255,255,255,!0,c):b=!0):(7E3>c-this.connecting?(this.dirty=!0,b=Math.floor(c/300)%4,this.drawString(38,15,"Connecting"+(0<b?".":"")+(1<b?".":"")+(2<b?".":""),128,128,128,!0,c)):this.drawString(38,15,"No Connection",96,96,96,!0,c),b=!0);b&&this.showAddress&&
|
||||||
|
this.drawString(38,27,this.originalAddress,48,48,48,!0,c);b=this.mouseOver&&233<=this.mouseX&&256>=this.mouseX&&1<=this.mouseY&&11>=this.mouseY;var g=!1;if(0<=this.currentStatus.pingToServer){b&&(a=[""+this.currentStatus.pingToServer+"ms"]);this.drawIcon(128,80+8*(150>this.currentStatus.pingToServer?0:300>this.currentStatus.pingToServer?1:600>this.currentStatus.pingToServer?2:1E3>this.currentStatus.pingToServer?3:4),10,7,243,3);c=""+this.currentStatus.onlineCount+"/"+this.currentStatus.maxCount;var e=
|
||||||
|
253-this.getStringWidth(c);g=!b&&this.mouseOver&&this.mouseX>=e-5&&256>=this.mouseX&&12<=this.mouseY&&23>=this.mouseY;this.drawString(e,14,c,128,128,128,!0);g&&(a=this.currentStatus.players)}else 7E3>c-this.connecting||this.connected?(this.dirty=!0,b&&(a=["Connecting..."]),this.drawIcon(138,80+8*Math.abs(Math.floor(c/100)%8-4),10,7,243,3)):(b&&(a=["No Connection"]),this.drawIcon(128,120,10,7,243,3));this.showCracked&&0<=this.currentStatus.pingToServer&&(this.currentStatus.serverCracked?this.drawIcon(144,
|
||||||
|
64,16,16,243,25,10,10):this.drawIcon(176,96,16,16,243,25,11,11),!g&&this.mouseOver&&239<=this.mouseX&&256>=this.mouseX&&22<=this.mouseY&&36>=this.mouseY&&(a=this.currentStatus.serverCracked?["Server is cracked"]:["Server has login"]));a&&this.mouseOver&&0!=a.length?this.showTooltip(a):this.tooltipCanvas.style.display="none"}};
|
||||||
|
ServerEmbed.prototype.ping=function(a,c,b,g,e){var y=this;c?this.showQueryName="undefined"!==typeof b&&!b:(c="Minecraft Server",this.showQueryName="undefined"===typeof b||!b);this.defaultName=c;this.showAddress=!g;this.originalAddress=a;"undefined"!==typeof e&&(this.showCracked=!e);0!=a.indexOf("ws://")&&0!=a.indexOf("wss://")&&(a=(0==window.location.href.indexOf("https:")?"wss":"ws")+"://"+a);null!=this.socket&&this.connected&&this.socket.close();this.currentStatus={serverName:c,serverCracked:!1,
|
||||||
|
pingSentTime:Date.now(),pingToServer:-1,motdLine1:"Connecting...",motdLine2:"",onlineCount:0,maxCount:0,players:[]};this.dirty=!0;if(this.connected||0<this.connecting)this.socket.close(),this.connected=!1,this.connecting=0,this.redraw();this.connecting=Date.now();var f=this;this.socket=new WebSocket(a);this.socket.binaryType="arraybuffer";this.socket.onopen=function(){f.socket.send("Accept: MOTD");f.connecting=0;f.connected=!0;f.dirty=!0};this.socket.onmessage=function(w){if(w.data)if("string"===
|
||||||
|
typeof w.data)try{var u=JSON.parse(w.data);if("motd"===u.type.toLowerCase()){f.dirty=!0;0<f.currentStatus.pingSentTime&&(f.currentStatus.pingToServer=Date.now()-f.currentStatus.pingSentTime,f.currentStatus.pingSentTime=0);f.currentStatus.serverName=y.showQueryName?u.name:y.defaultName;f.currentStatus.serverCracked=u.cracked;var A=u.data.motd;A&&0<A.length&&(f.currentStatus.motdLine1=A[0],1<A.length&&(f.currentStatus.motdLine2=A[1]));f.currentStatus.onlineCount=u.data.online;f.currentStatus.maxCount=
|
||||||
|
u.data.max;f.currentStatus.players=u.data.players||[]}}catch(B){f.currentStatus.motdLine1="ERROR: "+B}else u=new Uint8Array(w.data),16384==u.length&&(y.updateIconFromBytes(u),y.dirty=!0)};this.socket.onclose=function(w){f.connecting=0;f.connected=!1;f.dirty=!0};this.socket.onerror=function(w){(f.connected||0<f.connecting)&&f.socket.close();f.connecting=0;f.connected=!1;f.dirty=!0}};ServerEmbed.prototype.isActive=function(){return 0<self.connecting||self.connected};
|
||||||
|
ServerEmbed.prototype.setTooltip=function(a){if(this.isTooltipEnabled){var c=a.join();if(c!==this.tooltip||this.lastWidth!==this.canvas.width){for(var b=0,g=9*a.length,e=0;e<a.length;++e)b=Math.max(b,this.getStringWidth(a[e]));g+=3;this.tooltipCanvas.width=this.getPixelX(b+6);this.tooltipCanvas.height=this.getPixelY(g);b=this.ctx;this.ctx=this.tooltipCtx;this.ctx.imageSmoothingEnabled=!1;this.ctx.clearRect(0,0,this.tooltipCanvas.width,this.tooltipCanvas.height);this.ctx.fillStyle="#101010E0";this.ctx.fillRect(0,
|
||||||
|
0,this.tooltipCanvas.width,this.tooltipCanvas.height);for(e=0;e<a.length;++e)this.drawString(3,2+9*e,a[e],256,256,256,!0);this.ctx=b;this.tooltip=c;this.lastWidth=this.canvas.width}}};
|
||||||
|
ServerEmbed.prototype.showTooltip=function(a){this.dirty=!0;if(this.mouseOver){this.setTooltip(a);this.tooltipCanvas.style.display="block";a=this.mousePageX+this.getPixelX(4);var c=this.mousePageY-this.getPixelY(9);this.mousePageX+this.tooltipCanvas.width+2>window.innerWidth&&(a=window.innerWidth-this.tooltipCanvas.width-2);this.mousePageY+this.tooltipCanvas.height+2>window.innerHeight&&(c=window.innerHeight-this.tooltipCanvas.height-2,0>c&&(c=0));this.tooltipCanvas.style.left=a+"px";this.tooltipCanvas.style.top=
|
||||||
|
c+"px"}else this.tooltipCanvas.style.display="none"};ServerEmbed.prototype.updateIconFromBytes=function(a){this.iconCanvas||(this.iconCanvas=document.createElement("canvas"),this.iconCanvas.width=64,this.iconCanvas.height=64,this.iconContext=this.iconCanvas.getContext("2d"));for(var c=this.iconContext.createImageData(64,64),b=0;16384>b;++b)c.data[b]=a[b];this.iconContext.putImageData(c,0,0)};
|
BIN
icons_src/background.png
Normal file
After Width: | Height: | Size: 585 B |
BIN
icons_src/certificate_seal.ico
Normal file
After Width: | Height: | Size: 766 B |
BIN
icons_src/font.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
icons_src/icons.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
icons_src/key_padlock.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
icons_src/msg_warning.ico
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
icons_src/unknown_pack_64x64.png
Normal file
After Width: | Height: | Size: 13 KiB |
14
test.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Eaglercraft Server Embed Test</title>
|
||||||
|
<script type="text/javascript" src="embed.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.addEventListener("load", () => {
|
||||||
|
new ServerEmbed(document.getElementById("embed"), "75%").ping("127.0.0.1:25565");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body style="background-color:black;">
|
||||||
|
<div id="embed"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|