unmojang / drasl Goto Github PK
View Code? Open in Web Editor NEWYggdrasil-compatible API server for Minecraft
License: GNU General Public License v3.0
Yggdrasil-compatible API server for Minecraft
License: GNU General Public License v3.0
As said in the title, Drasl doesn't check for valid usernames, it allows special characters such as ñ, æ, å, ę, ç and many others, it doesn't even check for spaces on characters usernames (test test) and it can happen what a space is set after the username (such as "test "), causing weird Issues on a Minecraft server.
https://account.server.org/users/profiles/minecraft/name returns http code 500
Hi! I am currently using this behind oauth2-proxy with Keycloak, but would love the ability to integrate directly with OpenID Connect, SAML, or plain old LDAP.
https://api.minecraftservices.com
is hardcoded in prismarine-auth here.
node-minecraft-protocol's createClient
needs to be able to take a servicesServer
(currently only takes a authServer
and sessionServer
) and pass it to prismarine-auth.
I am new into go web development, and not properly know how to change directories, but I've tried set them how it described in docs, like this:
StateDirectory = "/srv/drasl"
DataDirectory = "/srv/drasl/data"
and nothing worked. Also it didn't really looks like StateDirectory and DataDirectory is really located at default values folders "/var/lib/drasl/" and "/usr/share/drasl".
Title
Hello! I have tried to set up Drasl on my server using Docker, but when I try to access the web UI or even ping the HTTP server it's running on the port is closed. And the thing is that I am not even connecting from the internet, but from my local network. I made sure that the port is accessible from the computer I'm trying to reach the HTTP server from, so I think that it must by an issue with Drasl. According to the logs which I have supplied below the webserver starts normally.
What I have tried to do (but it didn't help)
Here is my config file:
# Drasl default config file
# Example: drasl.example.com
Domain = "mcauth.frnsrv.ru"
# Example: My Drasl Instance
InstanceName = "REDACTED"
# Example: My Organization
ApplicationOwner = "REDACTED"
# Example: 127.0.0.1:25585
ListenAddress = "127.0.0.1:15585"
# Example: https://drasl.example.com
BaseURL = "https://mcauth.frnsrv.ru"
# List of usernames who automatically become admins of the Drasl instance
DefaultAdmins = ["GoodGameInfinity"]
# Amount of time until token expires in seconds, example: 604800 (1 week)
TokenExpireSec = 604800
[RegistrationNewPlayer]
Allow = true
AllowChoosingUUID = false
RequireInvite = true
Here are the logs copied from docker:
2023/12/23 20:24:42 Loading config from /etc/drasl/config.toml
2023/12/23 20:24:42 No users found! Here's an invite URL: https://mcauth.frnsrv.ru/drasl/registration?invite=REDACTED
⇨ http server started on 127.0.0.1:15585
Also some info:
I used Portainer to set up the docker container, it publishes the port 15585/TCP and mounts two binds. The Docker image I used is unmojang/drasl:latest from the Docker Hub.
In addition to configuration.md, recipes.md should contain example configurations for common setups.
FallbackAPIServer
s and RegistrationExistingPlayer
configsWhen adding "https://sessionserver.mojang.com" to FallbackSessionServers
, the Minecraft server can authenticate both custom Drasl users, and premium Microsoft accounts. The Minecraft server cannot, however, op premium accounts.
This is because when /op (player name)
executed, the Minecraft server uses the /profiles/minecraft
endpoint of the ServicesServer
to determine the UUID of who to make an operator. Adding an option for FallbackServiceServers
could enable this to work.
For security purposes, there should be a default limit on the size of a request body. Especially for skin/cape upload.
Is this compatible with the Velocity proxy?
Other options for databases other than sqlite
for perfomace reasons, such as postgres or mariadb/mysql,
gorm support that natively and would be easy to implement
Java 5 seems to struggle with viewing a lot of skins and capes, and they need to be transcoded to display in-game. Mojang's skin servers transcode skins and capes automatically, so this is a feature drasl lacks. Java 5 is the last version of Java supported on PowerPC architecture, and Minecraft versions up until 1.5.2 can support it. Currently drasl does not support pre-yggdrasil authentication so this issue was encountered when attempting to use a proxy I created, but it'd be nice to get this fixed before that changes so that anyone else running on obscure hardware will not encounter problems like this. The skins and capes that did not work were exported as a png from GIMP with the default settings. Here is a website that was able to transcode the skins into a format that worked: https://tinypng.com
Admin users should still be able to set capes/skins and change player names of other users and themselves regardless of the values of AllowChangingPlayerName
, AllowSkins
, and AllowCapes
.
Thank you!!!!!!!!!!
I want to say more but english is not my main lang,
i really appreciate your work!!!!!!!!!!
Getting this when running the server:
drasl-drasl-1 | 2023/11/26 10:17:49 Get "https://sessionserver.mojang.com/session/minecraft/hasJoined?serverId=...": x509: certificate signed by unknown authority
This is useful for users who would like to attempt more advanced configurations e.g. using unsupported launchers by editing hosts file and installing a self signed SSL certificate. So /account/users/profiles/minecraft/player is also accessible via /users/profiles/minecraft/player
Hey there!
I've recently found this project and wanted to try self-hosting it. I've followed the instructions in installation.md and configuration.md to get the sample docker-caddy configuration. I'm running this all over Tailscale. My files currently look like this:
docker-compose.yml
version: "3"
services:
caddy:
image: docker.io/caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./caddy/data:/data
- ./caddy/config:/config
drasl:
image: docker.io/unmojang/drasl
ports:
- "25585:25585"
volumes:
- ./config:/etc/drasl
- ./data:/var/lib/drasl
Caddyfile
# Should be the same as `Domain` in Drasl's config.toml
http://epic-server.faun-scala.ts.net
reverse_proxy :25585
(I have added http:// in front to disable automatic HTTPs as it does not play nice with my Tailscale config at the moment)
config.toml
# Drasl default config file
# Example: drasl.example.com
Domain = "epic-server.faun-scala.ts.net"
# Example: https://drasl.example.com
BaseURL = "http://epic-server.faun-scala.ts.net"
ListenAddress = "127.0.0.1:25585"
# List of usernames who automatically become admins of the Drasl instance
DefaultAdmins = ["cyrus"]
[RegistrationNewPlayer]
Allow = true
AllowChoosingUUID = true
RequireInvite = true
However, when I run docker compose up
and look at the log, Caddy
returns an empty page because of the following error:
{"level":"error","ts":1713493140.6753414,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:25585: connect: connection refused","request":{"remote_ip":"172.22.0.1","remote_port":"45926","client_ip":"172.22.0.1","proto":"HTTP/1.1","method":"GET","host":"epic-server.faun-scala.ts.net","uri":"/","headers":{"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"],"Accept-Encoding":["gzip, deflate"],"Connection":["keep-alive"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0"],"Sec-Gpc":["1"],"Upgrade-Insecure-Requests":["1"],"Accept-Language":["en-US,en;q=0.5"],"Dnt":["1"]}},"duration":0.000841842,"status":502,"err_id":"q1a5zcsr1","err_trace":"reverseproxy.statusError (reverseproxy.go:1267)"}
I cannot for the life of me get Drasl to not refuse the connection from Caddy, and would like some help figuring out what the hell is going on as someone which only recently dabbled in hosting things like Caddy
For now, just document setup using docker-compose and Caddy.
Inspo: https://plausible.io/docs/self-hosting. This guide was pretty easy to follow.
Later, package for AUR, nixpkgs, and have an setup guide with details for a more typical install.
Mostly to avoid rate-limiting, we should cache responses from Mojang/Ely.by/whoever's API for a (configurable) short amount of time instead of hitting them over and over.
Use gocache with an in-memory cache? Would rather not bring in redis or memcached.
There should be an option to disable uploading skins and capes, for instance to force only using ForwardSkins
to support vanilla clients.
authlib-injector has an API for skin/cape upload that's different from Mojang's.
help me to fix error in polymc
Title
How to reproduce:
For some reason, drasl required to invalidate last accessToken for the same clientToken before you can log again. It doesn't seem to be work as expected
Something like:
What is 6 × 5?
I'm not interested in implementing any kind of complex, inaccessible captcha like reCaptcha or HCaptcha. If you want to lock down your instance, use invites or RegistrationExistingPlayer
with RequireSkinVerification
.
For example to use skins from textures.minecraft.net so you dont need mods
I have a version here that has this but i can't program so the code is probably bad
What would it be on authlib injector
Drasl should have an API other than the Web UI.
I am unable to whitelist players that have never joined the server and am getting the error "That player does not exist". I can see in the Drasl logs that it indeed returns a 404 for the player. If I disable the whitelist then I can join just fine.
This is my Drasl config (url changed):
# Drasl default config file
# Example: drasl.example.com
Domain = "mca.xxxxx.com"
# Example: https://drasl.example.com
BaseURL = "https://mca.xxxxx.com"
#ListenAddress = "127.0.0.1:25585"
InstanceName = "mca.xxxxx.com"
ApplicationOwner = "TechCluster"
DefaultPreferredLanguage = "de"
# List of usernames who automatically become admins of the Drasl instance
DefaultAdmins = ["admin"]
[RegistrationNewPlayer]
Allow = true
RequireInvite = true
[[FallbackAPIServers]]
Nickname = "Mojang"
SessionURL = "https://sessionserver.mojang.com"
AccountURL = "https://api.mojang.com"
ServicesURL = "https://api.minecraftservices.com"
SkinDomains = ["textures.minecraft.net"]
CacheTTLSeconds = 60
I am using the fabric server version 0.15.10 with MC 1.20.4, launching using Aikar's flags.
Start script:
#!/bin/bash
sdk use java 17.0.10-tem # SDKMAN, can be ignored for this issue
java -Xmx3072M -Xms3072M -Dminecraft.api.env=custom -Dminecraft.api.auth.host=https://mca.xxxxx.com/auth -Dminecraft.api.account.host=https://mca.xxxxx.com/account -Dminecraft.api.session.host=https://mca.xxxxx.com/session -Dminecraft.api.services.host=https://mca.xxxxx.com/services -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+ParallelRefProcEnabled -XX:+PerfDisableSharedMem -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:G1HeapWastePercent=5 -XX:G1MaxNewSizePercent=40 -XX:G1MixedGCCountTarget=4 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1NewSizePercent=30 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:G1ReservePercent=20 -XX:InitiatingHeapOccupancyPercent=15 -XX:MaxGCPauseMillis=200 -XX:MaxTenuringThreshold=1 -XX:SurvivorRatio=32 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar fabric-server-mc.1.20.4-loader.0.15.10-launcher.1.0.1.jar nogui
Mods:
NoChatReports (same problem occurs without it as well)
enforce-secure-profile is currently set to false, but changing it to true does not fix the issue.
Is this a known issue with whitelist or is my config not set up properly?
Thanks!
Allow setting a default skin and/or cape for players who have not set one. If ForwardSkins
is enabled, forwarded skins should still override the default skin.
Continued from #4
See this comment from the authlib-injector author: elyby/accounts#2 (comment)
unsigned
query param?)X-Authlib-Injector-API-Location
for these routesHere is the commit where ely.by added support for authlib-injector: elyby/accounts@4856695
Can't find skins url to provide in CustomSkinLoader mod
Player specific commands break if there is for example a "notch" and "Notch" player, aswell as possibly many plugins or mods. Name system should be altered to be case-insensitive (e.g. API query for player "notch" returns the user "Notch" and the name change API reports that "NOTCH" is taken)
installation.md "Manual Installation" section has an error, the unit file in the repo will not work since the Makefile installs the drasl binary to /usr/local/bin, not /usr/bin. Probably the unit file should be changed.
Since PR #2611, MCC has support for adding custom yggdrasil servers.
Because one of the best uses of this server is creating more accounts for bots, I'd like to use my custom auth server with MCC.
Setting AccountType and AuthServer to the values results in a "Network Error" on the MCC side an a 404 on the Drasl side:
{"time":"2024-04-28T07:43:37.836718975Z","id":"","remote_ip":"xxxxx","host":"mca.xxxxx.com","method":"POST","uri":"/api/yggdrasil/authserver/authenticate","user_agent":"MCC/1.20.4","status":404,"error":"code=404, message=Not Found","latency":39509,"latency_human":"39.509µs","bytes_in":246,"bytes_out":50}
Configuration:
AccountType = "yggdrasil" # Account type: "mojang" OR "microsoft" OR "yggdrasil". Also affects interactive login in console.
Method = "mcc" # Microsoft Account sign-in method: "mcc" OR "browser". If the login always fails, please try to use the "browser" once.
AuthServer = { Host = "mca.xxxxx.com", Port = 443 } # Yggdrasil authlib server domain name and port.
Since you mentioned in the README that working with bots is a primary use case for this project it'd be great if usage with MCC could be documented or if you could let me know how.
Front end
authlib-injector
Authenticate
Account
Session
Services
Depends on #16
I have only checked for beta 1.7.3, since most beta players prefer this version, but to implement support for it should be feasible. Authlib did not exist at the time, instead URLs are hardcoded to be used, but they're all http so using jvm proxy argument you can reroute these API endpoints to any drasl instance.
For skins, http://s3.amazonaws.com/MinecraftSkins/PlayerName.png is checked, and the skin returned should be a 64x32 image (old skin format) with any layers merged into 1 layer.
For authentication, http://www.minecraft.net/game/joinserver.jsp is checked by the client and http://www.minecraft.net/game/checkserver.jsp is checked by the server. I do not know how these APIs work.
The skins endpoint is offline, but the joinserver.jsp and checkserver.jsp endpoints are online however they've been moved to https://session.minecraft.net (https://session.minecraft.net/game/joinserver.jsp and https://session.minecraft.net/game/checkserver.jsp respectively)
Here is the source code from beta 1.7.3 referencing these URLs that I hope can help with implementing this.
Authentication:
https://github.com/jacobo-mc/mc_b1.7.3_release/blob/main/1.7.3-LTS/src/minecraft/net/minecraft/src/NetClientHandler.java - Client
https://github.com/jacobo-mc/mc_b1.7.3_release/blob/main/1.7.3-LTS/src/minecraft_server/net/minecraft/src/ThreadLoginVerifier.java - Server
Skins:
https://github.com/jacobo-mc/mc_b1.7.3_release/blob/main/1.7.3-LTS/src/minecraft/net/minecraft/src/EntityPlayerSP.java - Self
https://github.com/jacobo-mc/mc_b1.7.3_release/blob/main/1.7.3-LTS/src/minecraft/net/minecraft/src/EntityOtherPlayerMP.java - Other players
root@9box:/home/cat/drasl# go test
{"time":"2023-06-17T23:47:23.575917554-04:00","level":"ERROR","prefix":"echo","file":"main.go","line":"53","message":"code=429, message=Too many requests. Try again later."}
{"time":"2023-06-17T23:47:23.576138652-04:00","level":"ERROR","prefix":"echo","file":"main.go","line":"53","message":"code=429, message=Too many requests. Try again later."}
2023/06/17 23:47:30 Get "publickeys": unsupported protocol scheme ""
{"time":"2023-06-17T23:47:30.064322696-04:00","level":"ERROR","prefix":"echo","file":"main.go","line":"53","message":"code=429, message=Too many requests. Try again later."}
{"time":"2023-06-17T23:47:30.06450828-04:00","level":"ERROR","prefix":"echo","file":"main.go","line":"53","message":"code=429, message=Too many requests. Try again later."}
{"time":"2023-06-17T23:47:30.064564569-04:00","level":"ERROR","prefix":"echo","file":"main.go","line":"53","message":"code=429, message=Too many requests. Try again later."}
--- FAIL: TestAccount (6.99s)
--- FAIL: TestAccount/Test_/users/profiles/minecraft/:playerName (0.00s)
account_test.go:62:
Error Trace: /home/cat/drasl/account_test.go:62
Error: Not equal:
expected: 200
actual : 500
Test: TestAccount/Test_/users/profiles/minecraft/:playerName
account_test.go:64:
Error Trace: /home/cat/drasl/account_test.go:64
Error: Expected nil, but got: &json.SyntaxError{msg:"invalid character 'I' looking for beginning of value", Offset:1}
Test: TestAccount/Test_/users/profiles/minecraft/:playerName
account_test.go:67:
Error Trace: /home/cat/drasl/account_test.go:67
Error: Not equal:
expected: ""
actual : "username"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-
+username
Test: TestAccount/Test_/users/profiles/minecraft/:playerName
account_test.go:72:
Error Trace: /home/cat/drasl/account_test.go:72
Error: Expected nil, but got: &errors.errorString{s:"record not found"}
Test: TestAccount/Test_/users/profiles/minecraft/:playerName
account_test.go:76:
Error Trace: /home/cat/drasl/account_test.go:76
Error: Expected nil, but got: &errors.errorString{s:"Invalid ID"}
Test: TestAccount/Test_/users/profiles/minecraft/:playerName
--- FAIL: TestAccount/Test_/profiles/minecraft (0.00s)
account_test.go:89:
Error Trace: /home/cat/drasl/account_test.go:89
Error: Not equal:
expected: 200
actual : 500
Test: TestAccount/Test_/profiles/minecraft
account_test.go:91:
Error Trace: /home/cat/drasl/account_test.go:91
Error: Expected nil, but got: &json.SyntaxError{msg:"invalid character 'I' looking for beginning of value", Offset:1}
Test: TestAccount/Test_/profiles/minecraft
account_test.go:96:
Error Trace: /home/cat/drasl/account_test.go:96
Error: Expected nil, but got: &errors.errorString{s:"record not found"}
For some reason, the game ignores my skin model setting and assumes every skin is classic.
According to this site, /session/minecraft/profile/<uuid>
should return something like this:
{
"id": "<profile identifier>",
"name": "<player name>",
"properties": [
{
"name": "textures",
"value": "<base64 string>",
"signature": "<base64 string; signed data using Yggdrasil's private key>" // Only provided if ?unsigned=false is appended to url
}
],
"profileActions": []
}
And value should decode to something like this:
{
"timestamp": <java time in ms>,
"profileId": "<profile uuid>",
"profileName": "<player name>",
"signatureRequired": true, // Only present if ?unsigned=false is appended to url
"textures": {
"SKIN": {
"url": "<player skin URL>",
"metadata": {
"model": "slim"
}
},
"CAPE": {
"url": "<player cape URL>"
}
}
}
However, my test account returns this:
{
"timestamp":1701318253009455404,
"profileId":"418bb580c44045a5bf3996f200b91c57",
"profileName":"tester",
"textures":
{
"SKIN":
{
"url":"https://drasl.localhost.lnet/drasl/texture/skin/676d6f7657076d3ee60f6e2b33e59cbbbb33dc6dbcf5242ccbceebf10773f71d.png",
"model":
{
"string":"slim"
}
}
}
}
There is no "metadata"
block.
Please note that I don't know what I'm doing and that this is just a guess.
OS: Artix Linux
Drasl: 1.0.0 (from the AUR)
Launcher: PollyMC
Server console throwing an error when trying to login:
[00:12:24 INFO]: UUID of player _daemon_process is 42385598-4714-42f0-bc3f-b8f7800fde10
[00:12:24 INFO]: _daemon_process joined the game
[00:12:24 INFO]: _daemon_process[/127.0.0.1:51636] logged in with entity id 380 at ([world]-1.5, 69.0, -7.5)
[00:12:24 ERROR]: Failed to verify Services signature
java.security.SignatureException: Signature length not correct: got 1 but was expecting 512
at sun.security.rsa.RSASignature.engineVerify(RSASignature.java:213) ~[?:?]
at java.security.Signature$Delegate.engineVerify(Signature.java:1435) ~[?:?]
at java.security.Signature.verify(Signature.java:789) ~[?:?]
at net.minecraft.util.SignatureValidator.verifySignature(SignatureValidator.java:30) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.util.SignatureValidator.lambda$from$3(SignatureValidator.java:54) ~[paper-1.20.2.jar:git-Paper-318]
at java.util.stream.MatchOps$1MatchSink.accept(MatchOps.java:90) ~[?:?]
at java.util.AbstractList$RandomAccessSpliterator.tryAdvance(AbstractList.java:706) ~[?:?]
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129) ~[?:?]
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527) ~[?:?]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513) ~[?:?]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[?:?]
at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230) ~[?:?]
at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196) ~[?:?]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
at java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:632) ~[?:?]
at net.minecraft.util.SignatureValidator.from(SignatureValidator.java:50) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.util.SignatureValidator.validate(SignatureValidator.java:23) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.world.entity.player.ProfilePublicKey$Data.validateSignature(ProfilePublicKey.java:54) ~[?:?]
at net.minecraft.world.entity.player.ProfilePublicKey.createValidated(ProfilePublicKey.java:26) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.network.chat.RemoteChatSession$Data.validate(RemoteChatSession.java:40) ~[?:?]
at net.minecraft.server.network.ServerGamePacketListenerImpl.handleChatSessionUpdate(ServerGamePacketListenerImpl.java:3458) ~[?:?]
at net.minecraft.network.protocol.game.ServerboundChatSessionUpdatePacket.handle(ServerboundChatSessionUpdatePacket.java:19) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.network.protocol.game.ServerboundChatSessionUpdatePacket.a(ServerboundChatSessionUpdatePacket.java:9) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.network.protocol.PacketUtils.lambda$ensureRunningOnSameThread$0(PacketUtils.java:53) ~[?:?]
at net.minecraft.server.TickTask.run(TickTask.java:18) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.util.thread.BlockableEventLoop.doRunTask(BlockableEventLoop.java:153) ~[?:?]
at net.minecraft.util.thread.ReentrantBlockableEventLoop.doRunTask(ReentrantBlockableEventLoop.java:24) ~[?:?]
at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:1324) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.server.MinecraftServer.d(MinecraftServer.java:193) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.util.thread.BlockableEventLoop.pollTask(BlockableEventLoop.java:126) ~[?:?]
at net.minecraft.server.MinecraftServer.pollTaskInternal(MinecraftServer.java:1301) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:1294) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.util.thread.BlockableEventLoop.managedBlock(BlockableEventLoop.java:136) ~[?:?]
at net.minecraft.server.MinecraftServer.waitUntilNextTick(MinecraftServer.java:1272) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1160) ~[paper-1.20.2.jar:git-Paper-318]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:315) ~[paper-1.20.2.jar:git-Paper-318]
at java.lang.Thread.run(Thread.java:833) ~[?:?]
[00:12:24 INFO]: _daemon_process lost connection: Invalid signature for profile public key.
Try restarting your game.
[00:12:24 INFO]: _daemon_process left the game
Currently, unmojang/drasl only provides images for AMD64, providing the images for ARM64 as well would be a useful addition as an easier way to run Drasl containers on ARM64 hosts, considering the widespread availability of the platform.
On the profile page, fall back to displaying a CSS-only skin view when JS is unavailable.
Could do the render serverside, which has the advantage of the skin preview being a proper image instead of a hacked-together mess of CSS. But it is more fun and cheaper on the server to use a big ball of CSS.
Could use https://github.com/rkkoszewski/minecraft-css-3d-skin-viewer/tree/master.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.