msnet

package module
v1.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2025 License: MIT Imports: 17 Imported by: 0

README

msnet

msnet is a pure Golang networking package for MapleStory

Installation

$ go get github.com/zhyonc/msnet@latest

Quick Start

package main

import (
	"log/slog"
	"net"

	"github.com/zhyonc/msnet"
	"github.com/zhyonc/msnet/enum"
)

type server struct {
	addr string
	lis  net.Listener
}

func NewServer(addr string) *server {
	s := &server{
		addr: addr,
	}
	return s
}

func (s *server) Run() {
	lis, err := net.Listen("tcp", s.addr)
	if err != nil {
		slog.Error("Failed to create tcp listener", "err", err)
		return
	}
	slog.Info("TCPListener is starting on " + s.addr)
	s.lis = lis
	for {
		if s.lis == nil {
			slog.Warn("TCPListener is nil")
			break
		}
		conn, err := s.lis.Accept()
		if err != nil {
			slog.Error("Failed to accept conn", "err", err)
			continue
		}
		slog.Info("New client connected", "addr", conn.RemoteAddr())
		cs := msnet.NewCClientSocket(s, conn, nil, nil)
		go cs.OnRead()
		cs.OnConnect()
	}
}

func (s *server) Shutdown() {
	s.lis.Close()
	s.lis = nil
}

func main() {
	msnet.New(&msnet.Setting{
		MSRegion: enum.GMS,
		MSVersion: 95,
		MSMinorVersion: "1",
	})
	s := NewServer("127.0.0.1:8484")
	s.Run()
}

Setting

  • MSRegion: MapleStory Regions including KMS(1)/KMST(2)/JMS(3)/CMS(4)/TMS(6)/MSEA(7)/GMS(8)/BMS(9)

  • MSVersion: MapleStory Client Version

  • MSMinorVersion: MapleStory Client Minor Version

  • RecvXOR: The server must use the same XOR key to recover the original packet

  • SendXOR: The client must use the same XOR key to recover the original packet

  • IsXORCipher: Used in versions about 2004

  • IsCycleAESKey:

    • Default is false, old AES key will be used, which is compatible with most earlier versions
    • If set true, cycle AES key will be used, which is compatible with newer versions
  • CustomAESKey(optional): It's used to instead of old AES key and cycle AES key

    • Decrypt: A 32-byte array used for decrypting data in CInPacket::DecryptData
    • Encrypt: A 32-byte array used for encrypting data in COutPacket::MakeBufferList
  • AESInitType(optional): Compatible with older versions based on tutorial

    • Default: Used in versions after about 2008
    • Duplicate: Used in versions about 2005~2007 (excluding TMS)
    • Shuffle: Used in TMS versions about 2005~2007

Packet

Header AESOFB Note
4 Bytes Any Bytes Except for the first packet
Decode

Decode packet length using XOR of two little-endian uint16 values from header
PacketLen = (Header[0]+Header[1]*0x100) ^ (Header[2]+Header[3]*0x100)

Encode

Encode packet length using little-endian XOR with sVersion and sendIV

  • sVersion = (^clientVer >> 8 & 0xFF) | ((^clientVer << 8) & 0xFF00)
  • a = int(sendIV[3])
  • a |= int(sendIV[2])<<8
  • a ^= sVersion
  • b = ((PacketLen << 8) & 0xFF00) | (PacketLen >> 8)
  • c = a ^ b
  • Header = [a>>8, a, c>>8, b]
Format
Opcode Data Note
2 Bytes Any Bytes Except for the connect packet
Connect Packet
Name PacketLen Version MinorVersionLen MinorVersion RecvIV SendIV Region Note
Connect 2 Bytes 2 Bytes 2 Bytes 1 Byte 4 Bytes 4 Bytes 1 Bytes The connect packet

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetLangBuf added in v1.0.2

func GetLangBuf(s string) []byte

func GetLangStr added in v1.0.2

func GetLangStr(buf []byte) string

func New

func New(setting *Setting)

func SetLogger

func SetLogger(backupDir string, filename string, level slog.Level, done chan bool)

Types

type CClientSocket

type CClientSocket interface {
	SetID(id int32)
	GetID() int32
	GetAddr() string
	XORRecv(buf []byte)
	XORSend(buf []byte)
	OnRead()
	OnConnect()
	OnAliveReq(LP_AliveReq uint16)
	OnMigrateCommand(LP_MigrateCommand uint16, ip string, port int16)
	SendPacket(oPacket COutPacket)
	Flush()
	OnError(err error)
	Close()
}

func NewCClientSocket

func NewCClientSocket(delegate CClientSocketDelegate, conn net.Conn, rcvIV []byte, sndIV []byte) CClientSocket

type CClientSocketDelegate added in v1.0.7

type CClientSocketDelegate interface {
	DebugInPacketLog(id int32, iPacket CInPacket)
	DebugOutPacketLog(id int32, oPacket COutPacket)
	ProcessPacket(cs CClientSocket, iPacket CInPacket)
	SocketClose(id int32)
}

type CInPacket

type CInPacket interface {
	AppendBuffer(pBuff []byte, bEnc bool)
	DecryptData(dwKey []byte)
	GetType() uint16
	GetTypeByte() uint8
	GetRemain() int
	GetOffset() int
	GetLength() int
	DecodeBool() bool
	Decode1() int8
	Decode2() int16
	Decode4() int32
	Decode8() int64
	DecodeFT() time.Time
	DecodeStr() string
	DecodeLocalStr() string
	DecodeLocalName() string
	DecodeBuffer(uSize int) []byte
	DumpString(nSize int) string
	Clear()
}

func NewCInPacket

func NewCInPacket(buf []byte) CInPacket

type COutPacket

type COutPacket interface {
	GetType() uint16
	GetTypeByte() uint8
	GetSendBuffer() []byte
	GetOffset() int
	GetLength() int
	EncodeBool(b bool)
	Encode1(n int8)
	Encode2(n int16)
	Encode4(n int32)
	Encode8(n int64)
	EncodeFT(t time.Time)
	EncodeStr(s string)
	EncodeLocalStr(s string)
	EncodeLocalName(s string)
	EncodeBuffer(buf []byte)
	MakeBufferList(uSeqBase uint16, bEnc bool, dwKey []byte) []byte
	DumpString(nSize int) string
}

func NewCOutPacket

func NewCOutPacket(nType uint16) COutPacket

func NewCOutPacketByte added in v1.0.9

func NewCOutPacketByte(nType uint8) COutPacket

type Setting

type Setting struct {
	MSRegion       enum.Region
	MSVersion      uint16
	MSMinorVersion string
	RecvXOR        uint8
	SendXOR        uint8
	IsXORCipher    bool
	IsCycleAESKey  bool
	AESKeyDecrypt  [32]byte
	AESKeyEncrypt  [32]byte
	AESInitType    enum.AESInitType
}

Directories

Path Synopsis
internal
opcode
Code generated by opcode_test, DO NOT EDIT.
Code generated by opcode_test, DO NOT EDIT.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL