Backup
This commit is contained in:
350
main.go
350
main.go
@@ -28,6 +28,7 @@ const (
|
||||
|
||||
var maxPlayers int32
|
||||
var icon string
|
||||
var iconData []byte
|
||||
var serverID = make([]byte, 20)
|
||||
|
||||
var serverPrivateKey *rsa.PrivateKey
|
||||
@@ -38,7 +39,8 @@ var usernameRegex = regexp.MustCompile("^[a-zA-Z0-9_]{3,16}$")
|
||||
var world World
|
||||
|
||||
func readIcon(fileName string) (icon string) {
|
||||
iconData, err := os.ReadFile(fileName)
|
||||
var err error
|
||||
iconData, err = os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -85,6 +87,7 @@ func main() {
|
||||
LabelInt: 0,
|
||||
URL: "https://brn.systems",
|
||||
}},
|
||||
TickRate: 20,
|
||||
}
|
||||
|
||||
var err error
|
||||
@@ -125,7 +128,6 @@ func handleRequest(conn net.Conn) {
|
||||
var player = Player{
|
||||
state: 0,
|
||||
conn: conn,
|
||||
name: "",
|
||||
version: 0,
|
||||
requestedAddress: "",
|
||||
requestedPort: 0,
|
||||
@@ -195,9 +197,9 @@ func handleRequest(conn net.Conn) {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.name = username
|
||||
player.Entity.Name = username
|
||||
player.uuid = playerUUID
|
||||
if !usernameRegex.MatchString(player.name) {
|
||||
if !usernameRegex.MatchString(player.Entity.Name) {
|
||||
errOut = errors.New("bad username")
|
||||
break
|
||||
}
|
||||
@@ -235,7 +237,7 @@ func handleRequest(conn net.Conn) {
|
||||
errOut = errors.New("joined session not found")
|
||||
break
|
||||
}
|
||||
if player.profile.ID != strings.Replace(player.uuid.String(), "-", "", -1) || player.profile.Name != player.name {
|
||||
if player.profile.ID != strings.Replace(player.uuid.String(), "-", "", -1) || player.profile.Name != player.Entity.Name {
|
||||
errOut = errors.New("wrong session name")
|
||||
break
|
||||
}
|
||||
@@ -354,6 +356,341 @@ func handleRequest(conn net.Conn) {
|
||||
case 4:
|
||||
switch packetID {
|
||||
|
||||
case 0x00: // Confirm Teleportation
|
||||
teleportID, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
// Handle teleport confirmation logic here
|
||||
if player.teleportID == teleportID {
|
||||
player.waitingForTeleportConfirm = false
|
||||
}
|
||||
|
||||
case 0x01: // Query Block Entity Tag
|
||||
transactionID, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
var position BlockPosition
|
||||
err = position.receivePosition(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
// Handle block entity query logic here
|
||||
player.queryBlockEntityTag(transactionID, position)
|
||||
|
||||
case 0x02: // Change Difficulty
|
||||
difficulty, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
// Change difficulty logic, ensure player is an operator
|
||||
if player.PermissionLevel >= 2 {
|
||||
world.Difficulty = difficulty
|
||||
for _, iterPlayer := range world.Players {
|
||||
iterPlayer.sendDifficulty()
|
||||
}
|
||||
}
|
||||
|
||||
case 0x03: // Acknowledge Message
|
||||
messageCount, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
// Acknowledge message logic here
|
||||
player.acknowledgeMessage(messageCount)
|
||||
|
||||
case 0x04, 0x05: // Chat Command & Signed Chat Command
|
||||
command, err := receiveString(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.processChatCommand(command)
|
||||
|
||||
case 0x06: // Chat Message
|
||||
message, err := receiveString(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
_ = receiveInt64(packetData)
|
||||
_ = receiveInt64(packetData)
|
||||
// Handle the chat message here
|
||||
player.handleChatMessage(message)
|
||||
|
||||
case 0x07: // Player Session
|
||||
//sessionId, err := receiveUUID(packetData)
|
||||
//if err != nil {
|
||||
// errOut = err
|
||||
// break
|
||||
//}
|
||||
//expiresAt := receiveInt64(packetData)
|
||||
//pubKeyLen, err := receiveVarint(packetData)
|
||||
//
|
||||
//maybe implement in the future
|
||||
|
||||
case 0x08: // Chunk Batch Received
|
||||
_ = receiveFloat32(packetData) //chunks per tick
|
||||
|
||||
case 0x09: // Client Status
|
||||
actionID, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
switch actionID {
|
||||
case 0:
|
||||
player.sendRespawn(true, true)
|
||||
case 1:
|
||||
player.sendAwardStatistics()
|
||||
}
|
||||
|
||||
case 0x0A: // Client Information
|
||||
// Read Locale (16-character string)
|
||||
locale, err := receiveString(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.locale = locale
|
||||
|
||||
// Read View Distance (1 byte)
|
||||
viewDistance, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.viewDistance = int8(viewDistance)
|
||||
|
||||
// Read Chat Mode (VarInt Enum)
|
||||
chatMode, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.chatMode = chatMode
|
||||
|
||||
// Read Chat Colors (Boolean)
|
||||
chatColors, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.chatColors = chatColors != 0
|
||||
|
||||
// Read Displayed Skin Parts (Unsigned Byte)
|
||||
displayedSkinParts, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.skinParts = displayedSkinParts
|
||||
|
||||
// Read Main Hand (VarInt Enum)
|
||||
mainHand, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.isRightHanded = mainHand == 1
|
||||
|
||||
// Read Enable Text Filtering (Boolean)
|
||||
enableTextFiltering, err := receiveBool(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.textFiltering = enableTextFiltering
|
||||
|
||||
// Read Allow Server Listings (Boolean)
|
||||
allowServerListings, err := receiveBool(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.serverListing = allowServerListings
|
||||
|
||||
// Successfully parsed the packet
|
||||
errOut = nil
|
||||
|
||||
case 0x0B: // Command Suggestions Request
|
||||
transactionId, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
text, err := receiveString(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.requestCommandSuggestions(transactionId, text)
|
||||
|
||||
case 0x0C: // Acknowledge Configuration
|
||||
player.state = 3
|
||||
|
||||
case 0x0D: // Click Container Button
|
||||
windowID, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
if windowID != player.WindowID {
|
||||
break
|
||||
}
|
||||
buttonID, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
_ = buttonID
|
||||
//TODO implement logic
|
||||
|
||||
case 0x0E: // Click Container
|
||||
// Parse fields and handle click container logic here
|
||||
windowID, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
if windowID != player.WindowID {
|
||||
break
|
||||
}
|
||||
|
||||
// Read StateID (VarInt)
|
||||
stateID, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
|
||||
// Read Slot (Short)
|
||||
var slot int16
|
||||
slot = receiveInt16(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
|
||||
// Read Button (Byte)
|
||||
button, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
|
||||
// Read Mode (VarInt)
|
||||
mode, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
|
||||
// Read number of ChangedSlots (VarInt)
|
||||
changedSlotsCount, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
|
||||
var packet ClickContainerPacket
|
||||
|
||||
// Initialize ChangedSlots slice
|
||||
packet.ChangedSlots = make([]Slot, changedSlotsCount)
|
||||
|
||||
// Read each Slot in the ChangedSlots array
|
||||
for i := 0; i < int(changedSlotsCount); i++ {
|
||||
slotData, err := readSlot(data)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
packet.ChangedSlots[i] = slotData
|
||||
}
|
||||
|
||||
// Read CarriedItem (ItemStack)
|
||||
carriedItem, err := readSlot(data)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
|
||||
// Populate the packet struct
|
||||
packet.WindowID = windowID
|
||||
packet.StateID = stateID
|
||||
packet.Slot = slot
|
||||
packet.Button = int8(button)
|
||||
packet.Mode = mode
|
||||
packet.CarriedItem = carriedItem
|
||||
player.handleClickContainer(packet)
|
||||
|
||||
case 0x0F: // Close Container
|
||||
windowID, err := packetData.ReadByte()
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.sendCloseContainer(windowID)
|
||||
|
||||
case 0x10: // Change Container ItemStack State
|
||||
slotID, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
windowID, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
state, err := receiveBool(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.changeContainerSlotState(slotID, windowID, state)
|
||||
|
||||
case 0x11: // Cookie Response
|
||||
key, err := receiveString(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
hasPayload, err := receiveBool(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
// Handle cookie response logic here
|
||||
player.handleCookieResponse(key, hasPayload)
|
||||
|
||||
case 0x12: // Serverbound Plugin Message
|
||||
channel, err := receiveString(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
data := packetData // Rest is the byte array
|
||||
player.handlePluginMessage(channel, data)
|
||||
|
||||
case 0x13: // Debug Sample Subscription
|
||||
sampleType, err := receiveVarint(packetData)
|
||||
if err != nil {
|
||||
errOut = err
|
||||
break
|
||||
}
|
||||
player.subscribeToDebugSample(sampleType)
|
||||
|
||||
case 0x14: // Edit Book
|
||||
// Parse fields and handle book editing logic
|
||||
player.handleEditBook(packetData)
|
||||
|
||||
default:
|
||||
errOut = fmt.Errorf("unexpected packet %x in play state", packetID)
|
||||
log.Println(errOut)
|
||||
@@ -368,7 +705,8 @@ func handleRequest(conn net.Conn) {
|
||||
}
|
||||
}
|
||||
|
||||
if errOut != nil {
|
||||
if //goland:noinspection GoDfaConstantCondition
|
||||
errOut != nil {
|
||||
log.Println(errOut.Error())
|
||||
_ = player.sendDisconnect(fmt.Sprintf("Your server thread crashed: %s", errOut.Error()))
|
||||
}
|
||||
|
Reference in New Issue
Block a user