Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
128cdcee52
|
|||
5a9e73d4f2
|
|||
a77942621e
|
4
.github/workflows/release.yml
vendored
@@ -45,14 +45,14 @@ jobs:
|
|||||||
- name: Create ZIP archive
|
- name: Create ZIP archive
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
run: |
|
run: |
|
||||||
cp -v ./config_example.ini ./build || exit 1
|
cp -v ./config_example.ini ./assets ./build/ || exit 1
|
||||||
pushd build || exit 1
|
pushd build || exit 1
|
||||||
ls -1 yggdrasil-* | while read LINE; do
|
ls -1 yggdrasil-* | while read LINE; do
|
||||||
PREFIX="${LINE%.*}"
|
PREFIX="${LINE%.*}"
|
||||||
SUFFIX="$(echo "$LINE" | grep -osE '\.\w+' || printf '')"
|
SUFFIX="$(echo "$LINE" | grep -osE '\.\w+' || printf '')"
|
||||||
cp -v "$LINE" "yggdrasil$SUFFIX"
|
cp -v "$LINE" "yggdrasil$SUFFIX"
|
||||||
FILE="../$PREFIX.zip"
|
FILE="../$PREFIX.zip"
|
||||||
zip -9v "$FILE" "yggdrasil$SUFFIX" *.ini
|
zip -9v "$FILE" "yggdrasil$SUFFIX" *.ini assets
|
||||||
DGST="$FILE.dgst"
|
DGST="$FILE.dgst"
|
||||||
openssl dgst -md5 "$FILE" | sed 's/([^)]*)//g' >>"$DGST"
|
openssl dgst -md5 "$FILE" | sed 's/([^)]*)//g' >>"$DGST"
|
||||||
openssl dgst -sha1 "$FILE" | sed 's/([^)]*)//g' >>"$DGST"
|
openssl dgst -sha1 "$FILE" | sed 's/([^)]*)//g' >>"$DGST"
|
||||||
|
@@ -10,6 +10,7 @@ COPY "build/yggdrasil-${TARGETOS}-${TARGETARCH}" /app/yggdrasil
|
|||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
VOLUME /app/data
|
VOLUME /app/data
|
||||||
|
COPY assets /app/data/assets/
|
||||||
|
|
||||||
WORKDIR /app/data
|
WORKDIR /app/data
|
||||||
ENTRYPOINT ["/app/yggdrasil"]
|
ENTRYPOINT ["/app/yggdrasil"]
|
||||||
|
4
Makefile
@@ -10,7 +10,7 @@ PACKAGE_NAME = yggdrasil.tar.gz
|
|||||||
|
|
||||||
default: $(BINARY)
|
default: $(BINARY)
|
||||||
|
|
||||||
$(BINARY):
|
$(BINARY):assets
|
||||||
$(GO_BUILD) -tags='nomsgpack,sqlite,mysql' -o $(BINARY)
|
$(GO_BUILD) -tags='nomsgpack,sqlite,mysql' -o $(BINARY)
|
||||||
|
|
||||||
get:
|
get:
|
||||||
@@ -23,7 +23,7 @@ assets:
|
|||||||
cp -r frontend/dist/. assets/
|
cp -r frontend/dist/. assets/
|
||||||
|
|
||||||
package:$(BINARY)
|
package:$(BINARY)
|
||||||
tar -zcf $(PACKAGE_NAME) $(BINARY) config_example.ini
|
tar -zcf $(PACKAGE_NAME) $(BINARY) config_example.ini assets
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-$(GO_CLEAN)
|
-$(GO_CLEAN)
|
||||||
|
BIN
frontend/public/player/slim/alex.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
frontend/public/player/slim/ari.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
frontend/public/player/slim/efe.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
frontend/public/player/slim/kai.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
frontend/public/player/slim/makena.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
frontend/public/player/slim/noor.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
frontend/public/player/slim/steve.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
frontend/public/player/slim/sunny.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
frontend/public/player/slim/zuri.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
frontend/public/player/wide/alex.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
frontend/public/player/wide/ari.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
frontend/public/player/wide/efe.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
frontend/public/player/wide/kai.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
frontend/public/player/wide/makena.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
frontend/public/player/wide/noor.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
frontend/public/player/wide/steve.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
frontend/public/player/wide/sunny.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
frontend/public/player/wide/zuri.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
11
main.go
@@ -22,13 +22,11 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"embed"
|
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"io/fs"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -40,9 +38,6 @@ import (
|
|||||||
"yggdrasil-go/util"
|
"yggdrasil-go/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed assets/*
|
|
||||||
var f embed.FS
|
|
||||||
|
|
||||||
type MetaCfg struct {
|
type MetaCfg struct {
|
||||||
ServerName string `ini:"server_name"`
|
ServerName string `ini:"server_name"`
|
||||||
ImplementationName string `ini:"implementation_name"`
|
ImplementationName string `ini:"implementation_name"`
|
||||||
@@ -139,11 +134,7 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
router.InitRouters(r, db, &serverMeta, meta.SkinRootUrl)
|
router.InitRouters(r, db, &serverMeta, meta.SkinRootUrl)
|
||||||
assetsFs, err := fs.Sub(f, "assets")
|
r.Static("/profile", "assets")
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
r.StaticFS("/profile", http.FS(assetsFs))
|
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: serverCfg.ServerAddress,
|
Addr: serverCfg.ServerAddress,
|
||||||
Handler: r,
|
Handler: r,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022. Gardel <sunxinao@hotmail.com> and contributors
|
* Copyright (C) 2022-2023. Gardel <sunxinao@hotmail.com> and contributors
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
@@ -18,8 +18,11 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/pem"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"yggdrasil-go/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MetaInfo struct {
|
type MetaInfo struct {
|
||||||
@@ -42,17 +45,31 @@ type ServerMeta struct {
|
|||||||
SignaturePublickey string `json:"signaturePublickey"`
|
SignaturePublickey string `json:"signaturePublickey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KeyPair struct {
|
||||||
|
PrivateKey string `json:"privateKey,omitempty"`
|
||||||
|
PublicKey string `json:"publicKey,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PublicKeys struct {
|
||||||
|
ProfilePropertyKeys []KeyPair `json:"profilePropertyKeys,omitempty"`
|
||||||
|
PlayerCertificateKeys []KeyPair `json:"playerCertificateKeys,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type HomeRouter interface {
|
type HomeRouter interface {
|
||||||
Home(c *gin.Context)
|
Home(c *gin.Context)
|
||||||
|
PublicKeys(c *gin.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
type homeRouterImpl struct {
|
type homeRouterImpl struct {
|
||||||
serverMeta ServerMeta
|
serverMeta ServerMeta
|
||||||
|
myPubKey KeyPair
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHomeRouter(meta *ServerMeta) HomeRouter {
|
func NewHomeRouter(meta *ServerMeta) HomeRouter {
|
||||||
|
signaturePubKey, _ := pem.Decode([]byte(meta.SignaturePublickey))
|
||||||
homeRouter := homeRouterImpl{
|
homeRouter := homeRouterImpl{
|
||||||
serverMeta: *meta,
|
serverMeta: *meta,
|
||||||
|
myPubKey: KeyPair{PublicKey: base64.StdEncoding.EncodeToString(signaturePubKey.Bytes)},
|
||||||
}
|
}
|
||||||
return &homeRouter
|
return &homeRouter
|
||||||
}
|
}
|
||||||
@@ -61,3 +78,15 @@ func NewHomeRouter(meta *ServerMeta) HomeRouter {
|
|||||||
func (h *homeRouterImpl) Home(c *gin.Context) {
|
func (h *homeRouterImpl) Home(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, h.serverMeta)
|
c.JSON(http.StatusOK, h.serverMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *homeRouterImpl) PublicKeys(c *gin.Context) {
|
||||||
|
publicKeys := PublicKeys{}
|
||||||
|
err := util.GetObject("https://api.minecraftservices.com/publickeys", &publicKeys)
|
||||||
|
if err != nil {
|
||||||
|
util.HandleError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
publicKeys.ProfilePropertyKeys = append(publicKeys.ProfilePropertyKeys, h.myPubKey)
|
||||||
|
publicKeys.PlayerCertificateKeys = append(publicKeys.PlayerCertificateKeys, h.myPubKey)
|
||||||
|
c.JSON(http.StatusOK, publicKeys)
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022. Gardel <sunxinao@hotmail.com> and contributors
|
* Copyright (C) 2022-2023. Gardel <sunxinao@hotmail.com> and contributors
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
@@ -72,5 +72,9 @@ func InitRouters(router *gin.Engine, db *gorm.DB, meta *ServerMeta, skinRootUrl
|
|||||||
api.DELETE("/user/profile/:uuid/:textureType", textureRouter.DeleteTexture)
|
api.DELETE("/user/profile/:uuid/:textureType", textureRouter.DeleteTexture)
|
||||||
api.GET("/users/profiles/minecraft/:username", userRouter.UsernameToUUID)
|
api.GET("/users/profiles/minecraft/:username", userRouter.UsernameToUUID)
|
||||||
}
|
}
|
||||||
router.POST("/minecraftservices/player/certificates", userRouter.ProfileKey)
|
minecraftservices := router.Group("/minecraftservices")
|
||||||
|
{
|
||||||
|
minecraftservices.POST("/player/certificates", userRouter.ProfileKey)
|
||||||
|
minecraftservices.GET("/publickeys", homeRouter.PublicKeys)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|