mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-12 15:04:38 +01:00
378 lines
16 KiB
Go
378 lines
16 KiB
Go
package signserver
|
||
|
||
import (
|
||
"erupe-ce/common/byteframe"
|
||
ps "erupe-ce/common/pascalstring"
|
||
"erupe-ce/common/stringsupport"
|
||
_config "erupe-ce/config"
|
||
"erupe-ce/server/channelserver"
|
||
"fmt"
|
||
"strings"
|
||
"time"
|
||
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
func (s *Session) makeSignResponse(uid uint32) []byte {
|
||
// Get the characters from the DB.
|
||
chars, err := s.server.getCharactersForUser(uid)
|
||
if len(chars) == 0 && uid != 0 {
|
||
err = s.server.newUserChara(uid)
|
||
if err == nil {
|
||
chars, err = s.server.getCharactersForUser(uid)
|
||
}
|
||
}
|
||
if err != nil {
|
||
s.logger.Warn("Error getting characters from DB", zap.Error(err))
|
||
}
|
||
|
||
bf := byteframe.NewByteFrame()
|
||
var tokenID uint32
|
||
var sessToken string
|
||
if uid == 0 && s.psn != "" {
|
||
tokenID, sessToken, err = s.server.registerPsnToken(s.psn)
|
||
} else {
|
||
tokenID, sessToken, err = s.server.registerUidToken(uid)
|
||
}
|
||
if err != nil {
|
||
bf.WriteUint8(uint8(SIGN_EABORT))
|
||
return bf.Data()
|
||
}
|
||
|
||
if s.client == PS3 && (s.server.erupeConfig.PatchServerFile == "" || s.server.erupeConfig.PatchServerManifest == "") {
|
||
bf.WriteUint8(uint8(SIGN_EABORT))
|
||
return bf.Data()
|
||
}
|
||
|
||
bf.WriteUint8(uint8(SIGN_SUCCESS))
|
||
bf.WriteUint8(2) // patch server count
|
||
bf.WriteUint8(1) // entrance server count
|
||
bf.WriteUint8(uint8(len(chars)))
|
||
bf.WriteUint32(tokenID)
|
||
bf.WriteBytes([]byte(sessToken))
|
||
bf.WriteUint32(uint32(channelserver.TimeAdjusted().Unix()))
|
||
if s.client == PS3 {
|
||
ps.Uint8(bf, fmt.Sprintf("%s/ps3", s.server.erupeConfig.PatchServerManifest), false)
|
||
ps.Uint8(bf, fmt.Sprintf("%s/ps3", s.server.erupeConfig.PatchServerFile), false)
|
||
} else {
|
||
ps.Uint8(bf, s.server.erupeConfig.PatchServerManifest, false)
|
||
ps.Uint8(bf, s.server.erupeConfig.PatchServerFile, false)
|
||
}
|
||
if strings.Split(s.rawConn.RemoteAddr().String(), ":")[0] == "127.0.0.1" {
|
||
ps.Uint8(bf, fmt.Sprintf("127.0.0.1:%d", s.server.erupeConfig.Entrance.Port), false)
|
||
} else {
|
||
ps.Uint8(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.Host, s.server.erupeConfig.Entrance.Port), false)
|
||
}
|
||
|
||
lastPlayed := uint32(0)
|
||
for _, char := range chars {
|
||
if lastPlayed == 0 {
|
||
lastPlayed = char.ID
|
||
}
|
||
bf.WriteUint32(char.ID)
|
||
if s.server.erupeConfig.DebugOptions.MaxLauncherHR {
|
||
bf.WriteUint16(999)
|
||
} else {
|
||
bf.WriteUint16(char.HR)
|
||
}
|
||
bf.WriteUint16(char.WeaponType) // Weapon, 0-13.
|
||
bf.WriteUint32(char.LastLogin) // Last login date, unix timestamp in seconds.
|
||
bf.WriteBool(char.IsFemale) // Sex, 0=male, 1=female.
|
||
bf.WriteBool(char.IsNewCharacter) // Is new character, 1 replaces character name with ?????.
|
||
bf.WriteUint8(0) // Old GR
|
||
bf.WriteBool(true) // Use uint16 GR, no reason not to
|
||
bf.WriteBytes(stringsupport.PaddedString(char.Name, 16, true)) // Character name
|
||
bf.WriteBytes(stringsupport.PaddedString(char.UnkDescString, 32, false)) // unk str
|
||
if s.server.erupeConfig.RealClientMode >= _config.G7 {
|
||
bf.WriteUint16(char.GR)
|
||
bf.WriteUint8(0) // Unk
|
||
bf.WriteUint8(0) // Unk
|
||
}
|
||
}
|
||
|
||
friends := s.server.getFriendsForCharacters(chars)
|
||
if len(friends) == 0 {
|
||
bf.WriteUint8(0)
|
||
} else {
|
||
if len(friends) > 255 {
|
||
bf.WriteUint8(255)
|
||
bf.WriteUint16(uint16(len(friends)))
|
||
} else {
|
||
bf.WriteUint8(uint8(len(friends)))
|
||
}
|
||
for _, friend := range friends {
|
||
bf.WriteUint32(friend.CID)
|
||
bf.WriteUint32(friend.ID)
|
||
ps.Uint8(bf, friend.Name, true)
|
||
}
|
||
}
|
||
|
||
guildmates := s.server.getGuildmatesForCharacters(chars)
|
||
if len(guildmates) == 0 {
|
||
bf.WriteUint8(0)
|
||
} else {
|
||
if len(guildmates) > 255 {
|
||
bf.WriteUint8(255)
|
||
bf.WriteUint16(uint16(len(guildmates)))
|
||
} else {
|
||
bf.WriteUint8(uint8(len(guildmates)))
|
||
}
|
||
for _, guildmate := range guildmates {
|
||
bf.WriteUint32(guildmate.CID)
|
||
bf.WriteUint32(guildmate.ID)
|
||
ps.Uint8(bf, guildmate.Name, true)
|
||
}
|
||
}
|
||
|
||
if s.server.erupeConfig.HideLoginNotice {
|
||
bf.WriteBool(false)
|
||
} else {
|
||
bf.WriteBool(true)
|
||
bf.WriteUint8(0)
|
||
bf.WriteUint8(0)
|
||
ps.Uint16(bf, strings.Join(s.server.erupeConfig.LoginNotices[:], "<PAGE>"), true)
|
||
}
|
||
|
||
bf.WriteUint32(s.server.getLastCID(uid))
|
||
bf.WriteUint32(s.server.getUserRights(uid))
|
||
|
||
namNGWords := []string{"test", "痴女", "てすと"}
|
||
msgNGWords := []string{"test", "痴女", "てすと"}
|
||
|
||
filters := byteframe.NewByteFrame()
|
||
filters.SetLE()
|
||
filters.WriteNullTerminatedBytes([]byte("smc"))
|
||
smc := byteframe.NewByteFrame()
|
||
smc.SetLE()
|
||
smcData := []struct {
|
||
charGroup [][]rune
|
||
}{
|
||
{[][]rune{{'='}, {'='}}},
|
||
{[][]rune{{')'}, {')'}}},
|
||
{[][]rune{{'('}, {'('}}},
|
||
{[][]rune{{'!'}, {'!'}}},
|
||
{[][]rune{{'/'}, {'/'}}},
|
||
{[][]rune{{'+'}, {'+'}}},
|
||
{[][]rune{{'&'}, {'&'}}},
|
||
{[][]rune{{'ぼ'}, {'ボ'}, {'ホ', '゙'}, {'ほ', '゙'}, {'ホ', '゙'}, {'ほ', '゛'}, {'ホ', '゛'}, {'ホ', '゛'}}},
|
||
{[][]rune{{'べ'}, {'ベ'}, {'ヘ', '゙'}, {'へ', '゙'}, {'ヘ', '゙'}, {'へ', '゛'}, {'ヘ', '゛'}, {'ヘ', '゛'}}},
|
||
{[][]rune{{'で'}, {'デ'}, {'テ', '゙'}, {'て', '゙'}, {'テ', '゙'}, {'て', '゛'}, {'テ', '゛'}, {'テ', '゛'}, {'〒', '゛'}, {'〒', '゙'}, {'乙', '゙'}, {'乙', '゛'}}},
|
||
{[][]rune{{'び'}, {'ビ'}, {'ヒ', '゙'}, {'ひ', '゙'}, {'ヒ', '゙'}, {'ひ', '゛'}, {'ヒ', '゛'}, {'ヒ', '゛'}}},
|
||
{[][]rune{{'ど'}, {'ド'}, {'ト', '゙'}, {'と', '゙'}, {'ト', '゙'}, {'と', '゛'}, {'ト', '゛'}, {'ト', '゛'}, {'┣', '゙'}, {'┣', '゛'}, {'├', '゙'}, {'├', '゛'}}},
|
||
{[][]rune{{'ば'}, {'バ'}, {'ハ', '゙'}, {'は', '゙'}, {'ハ', '゙'}, {'八', '゙'}, {'は', '゛'}, {'ハ', '゛'}, {'ハ', '゛'}, {'八', '゛'}}},
|
||
{[][]rune{{'つ', '゙'}, {'ヅ'}, {'ツ', '゙'}, {'つ', '゛'}, {'ツ', '゛'}, {'ツ', '゙'}, {'ツ', '゛'}, {'づ'}, {'っ', '゙'}, {'ッ', '゙'}, {'ッ', '゙'}, {'っ', '゛'}, {'ッ', '゛'}, {'ッ', '゛'}}},
|
||
{[][]rune{{'ぶ'}, {'ブ'}, {'フ', '゙'}, {'ヴ'}, {'ウ', '゙'}, {'う', '゛'}, {'う', '゙'}, {'ウ', '゙'}, {'ゥ', '゙'}, {'ぅ', '゙'}, {'ふ', '゙'}, {'フ', '゙'}, {'フ', '゛'}}},
|
||
{[][]rune{{'ぢ'}, {'ヂ'}, {'チ', '゙'}, {'ち', '゙'}, {'チ', '゙'}, {'ち', '゛'}, {'チ', '゛'}, {'チ', '゛'}, {'千', '゛'}, {'千', '゙'}}},
|
||
{[][]rune{{'だ'}, {'ダ'}, {'タ', '゙'}, {'た', '゙'}, {'タ', '゙'}, {'夕', '゙'}, {'た', '゛'}, {'タ', '゛'}, {'タ', '゛'}, {'夕', '゛'}}},
|
||
{[][]rune{{'ぞ'}, {'ゾ'}, {'ソ', '゙'}, {'そ', '゙'}, {'ソ', '゙'}, {'そ', '゛'}, {'ソ', '゛'}, {'ソ', '゛'}, {'ン', '゙'}, {'ン', '゛'}, {'ン', '゛'}, {'ン', '゙'}, {'リ', '゙'}, {'リ', '゙'}, {'リ', '゛'}, {'リ', '゛'}}},
|
||
{[][]rune{{'ぜ'}, {'セ', '゙'}, {'せ', '゙'}, {'セ', '゙'}, {'せ', '゛'}, {'セ', '゛'}, {'セ', '゛'}, {'ゼ'}}},
|
||
{[][]rune{{'ず'}, {'ズ'}, {'ス', '゙'}, {'す', '゙'}, {'ス', '゙'}, {'す', '゛'}, {'ス', '゛'}, {'ス', '゛'}}},
|
||
{[][]rune{{'じ'}, {'ジ'}, {'シ', '゙'}, {'し', '゙'}, {'シ', '゙'}, {'し', '゛'}, {'シ', '゛'}, {'シ', '゛'}}},
|
||
{[][]rune{{'ざ'}, {'ザ'}, {'サ', '゙'}, {'さ', '゙'}, {'サ', '゙'}, {'さ', '゛'}, {'サ', '゛'}, {'サ', '゛'}}},
|
||
{[][]rune{{'ご'}, {'ゴ'}, {'コ', '゙'}, {'こ', '゙'}, {'コ', '゙'}, {'こ', '゛'}, {'コ', '゛'}, {'コ', '゛'}}},
|
||
{[][]rune{{'げ'}, {'ゲ'}, {'ケ', '゙'}, {'け', '゙'}, {'ケ', '゙'}, {'け', '゛'}, {'ケ', '゛'}, {'ケ', '゛'}, {'ヶ', '゙'}, {'ヶ', '゛'}}},
|
||
{[][]rune{{'ぐ'}, {'グ'}, {'ク', '゙'}, {'く', '゙'}, {'ク', '゙'}, {'く', '゛'}, {'ク', '゛'}, {'ク', '゛'}}},
|
||
{[][]rune{{'ぎ'}, {'ギ'}, {'キ', '゙'}, {'き', '゙'}, {'キ', '゙'}, {'き', '゛'}, {'キ', '゛'}, {'キ', '゛'}}},
|
||
{[][]rune{{'が'}, {'ガ'}, {'カ', '゙'}, {'ヵ', '゙'}, {'カ', '゙'}, {'か', '゙'}, {'力', '゙'}, {'ヵ', '゛'}, {'カ', '゛'}, {'か', '゛'}, {'力', '゛'}, {'カ', '゛'}}},
|
||
{[][]rune{{'を'}, {'ヲ'}, {'ヲ'}}},
|
||
{[][]rune{{'わ'}, {'ワ'}, {'ワ'}, {'ヮ'}}},
|
||
{[][]rune{{'ろ'}, {'ロ'}, {'ロ'}, {'□'}, {'口'}}},
|
||
{[][]rune{{'れ'}, {'レ'}, {'レ'}}},
|
||
{[][]rune{{'る'}, {'ル'}, {'ル'}}},
|
||
{[][]rune{{'り'}, {'リ'}, {'リ'}}},
|
||
{[][]rune{{'ら'}, {'ラ'}, {'ラ'}}},
|
||
{[][]rune{{'よ'}, {'ヨ'}, {'ヨ'}, {'ョ'}, {'ょ'}, {'ョ'}}},
|
||
{[][]rune{{'ゆ'}, {'ユ'}, {'ユ'}, {'ュ'}, {'ゅ'}, {'ュ'}}},
|
||
{[][]rune{{'や'}, {'ヤ'}, {'ヤ'}, {'ャ'}, {'ゃ'}, {'ャ'}}},
|
||
{[][]rune{{'も'}, {'モ'}, {'モ'}}},
|
||
{[][]rune{{'め'}, {'メ'}, {'メ'}, {'M', 'E'}}},
|
||
{[][]rune{{'む'}, {'ム'}, {'ム'}}},
|
||
{[][]rune{{'み'}, {'ミ'}, {'ミ'}}},
|
||
{[][]rune{{'ま'}, {'マ'}, {'マ'}}},
|
||
{[][]rune{{'ほ'}, {'ホ'}, {'ホ'}}},
|
||
{[][]rune{{'へ'}, {'ヘ'}, {'ヘ'}}},
|
||
{[][]rune{{'ふ'}, {'フ'}, {'フ'}}},
|
||
{[][]rune{{'ひ'}, {'ヒ'}, {'ヒ'}}},
|
||
{[][]rune{{'は'}, {'ハ'}, {'ハ'}, {'八'}}},
|
||
{[][]rune{{'の'}, {'ノ'}, {'ノ'}}},
|
||
{[][]rune{{'ね'}, {'ネ'}, {'ネ'}}},
|
||
{[][]rune{{'ぬ'}, {'ヌ'}, {'ヌ'}}},
|
||
{[][]rune{{'に'}, {'ニ'}, {'ニ'}, {'二'}}},
|
||
{[][]rune{{'な'}, {'ナ'}, {'ナ'}}},
|
||
{[][]rune{{'と'}, {'ト'}, {'ト'}, {'┣'}, {'├'}}},
|
||
{[][]rune{{'て'}, {'テ'}, {'テ'}, {'〒'}, {'乙'}}},
|
||
{[][]rune{{'つ'}, {'ツ'}, {'ツ'}, {'っ'}, {'ッ'}, {'ッ'}}},
|
||
{[][]rune{{'ち'}, {'チ'}, {'チ'}, {'千'}}},
|
||
{[][]rune{{'た'}, {'タ'}, {'タ'}, {'夕'}}},
|
||
{[][]rune{{'そ'}, {'ソ'}, {'ソ'}}},
|
||
{[][]rune{{'せ'}, {'セ'}, {'セ'}}},
|
||
{[][]rune{{'す'}, {'ス'}, {'ス'}}},
|
||
{[][]rune{{'し'}, {'シ'}, {'シ'}}},
|
||
{[][]rune{{'さ'}, {'サ'}, {'サ'}}},
|
||
{[][]rune{{'こ'}, {'コ'}, {'コ'}}},
|
||
{[][]rune{{'け'}, {'ケ'}, {'ケ'}, {'ヶ'}}},
|
||
{[][]rune{{'く'}, {'ク'}, {'ク'}}},
|
||
{[][]rune{{'き'}, {'キ'}, {'キ'}}},
|
||
{[][]rune{{'か'}, {'カ'}, {'カ'}, {'ヵ'}, {'力'}}},
|
||
{[][]rune{{'お'}, {'オ'}, {'オ'}, {'ォ'}, {'ぉ'}, {'ォ'}}},
|
||
{[][]rune{{'え'}, {'エ'}, {'エ'}, {'ェ'}, {'ぇ'}, {'ェ'}, {'工'}}},
|
||
{[][]rune{{'う'}, {'ウ'}, {'ウ'}, {'ゥ'}, {'ぅ'}, {'ゥ'}}},
|
||
{[][]rune{{'い'}, {'イ'}, {'イ'}, {'ィ'}, {'ぃ'}, {'ィ'}}},
|
||
{[][]rune{{'あ'}, {'ア'}, {'ァ'}, {'ア'}, {'ぁ'}, {'ァ'}}},
|
||
{[][]rune{{'ー'}, {'―'}, {'‐'}, {'-'}, {'-'}, {'ー'}, {'一'}}},
|
||
{[][]rune{{'9'}, {'9'}}},
|
||
{[][]rune{{'8'}, {'8'}}},
|
||
{[][]rune{{'7'}, {'7'}}},
|
||
{[][]rune{{'6'}, {'6'}}},
|
||
{[][]rune{{'5'}, {'5'}}},
|
||
{[][]rune{{'4'}, {'4'}}},
|
||
{[][]rune{{'3'}, {'3'}}},
|
||
{[][]rune{{'2'}, {'2'}}},
|
||
{[][]rune{{'1'}, {'1'}}},
|
||
{[][]rune{{'ぽ'}, {'ポ'}, {'ホ', '゚'}, {'ほ', '゚'}, {'ホ', '゚'}, {'ホ', '°'}, {'ほ', '°'}, {'ホ', '°'}}},
|
||
{[][]rune{{'ぺ'}, {'ペ'}, {'ヘ', '゚'}, {'へ', '゚'}, {'ヘ', '゚'}, {'ヘ', '°'}, {'へ', '°'}, {'ヘ', '°'}}},
|
||
{[][]rune{{'ぷ'}, {'プ'}, {'フ', '゚'}, {'ふ', '゚'}, {'フ', '゚'}, {'フ', '°'}, {'ふ', '°'}, {'フ', '°'}}},
|
||
{[][]rune{{'ぴ'}, {'ピ'}, {'ヒ', '゚'}, {'ひ', '゚'}, {'ヒ', '゚'}, {'ヒ', '°'}, {'ひ', '°'}, {'ヒ', '°'}}},
|
||
{[][]rune{{'ぱ'}, {'パ'}, {'ハ', '゚'}, {'は', '゚'}, {'ハ', '゚'}, {'ハ', '°'}, {'は', '°'}, {'ハ', '°'}, {'八', '゚'}, {'八', '゜'}}},
|
||
{[][]rune{{'z'}, {'z'}, {'Z'}, {'Z'}, {'Ζ'}}},
|
||
{[][]rune{{'y'}, {'y'}, {'Y'}, {'Y'}, {'Υ'}, {'У'}, {'у'}}},
|
||
{[][]rune{{'x'}, {'x'}, {'X'}, {'X'}, {'Χ'}, {'χ'}, {'Х'}, {'×'}, {'х'}}},
|
||
{[][]rune{{'w'}, {'w'}, {'W'}, {'W'}, {'ω'}, {'Ш'}, {'ш'}, {'щ'}}},
|
||
{[][]rune{{'v'}, {'v'}, {'V'}, {'V'}, {'ν'}, {'υ'}}},
|
||
{[][]rune{{'u'}, {'u'}, {'U'}, {'U'}, {'μ'}, {'∪'}}},
|
||
{[][]rune{{'t'}, {'t'}, {'T'}, {'T'}, {'Τ'}, {'τ'}, {'Т'}, {'т'}}},
|
||
{[][]rune{{'s'}, {'s'}, {'S'}, {'S'}, {'∫'}, {'$'}, {'$'}}},
|
||
{[][]rune{{'r'}, {'r'}, {'R'}, {'R'}, {'Я'}, {'я'}}},
|
||
{[][]rune{{'q'}, {'q'}, {'Q'}, {'Q'}}},
|
||
{[][]rune{{'p'}, {'p'}, {'P'}, {'P'}, {'Ρ'}, {'ρ'}, {'Р'}, {'р'}}},
|
||
{[][]rune{{'o'}, {'o'}, {'O'}, {'O'}, {'○'}, {'Ο'}, {'ο'}, {'О'}, {'о'}, {'◯'}, {'〇'}, {'0'}, {'0'}}},
|
||
{[][]rune{{'n'}, {'n'}, {'N'}, {'N'}, {'Ν'}, {'η'}, {'ン'}, {'ん'}, {'ン'}}},
|
||
{[][]rune{{'m'}, {'m'}, {'M'}, {'M'}, {'Μ'}, {'М'}, {'м'}}},
|
||
{[][]rune{{'l'}, {'l'}, {'L'}, {'L'}, {'|'}}},
|
||
{[][]rune{{'k'}, {'k'}, {'K'}, {'K'}, {'Κ'}, {'κ'}, {'К'}, {'к'}}},
|
||
{[][]rune{{'j'}, {'j'}, {'J'}, {'J'}}},
|
||
{[][]rune{{'i'}, {'i'}, {'I'}, {'I'}, {'Ι'}}},
|
||
{[][]rune{{'h'}, {'h'}, {'H'}, {'H'}, {'Η'}, {'Н'}, {'н'}}},
|
||
{[][]rune{{'f'}, {'f'}, {'F'}, {'F'}}},
|
||
{[][]rune{{'g'}, {'g'}, {'G'}, {'G'}}},
|
||
{[][]rune{{'e'}, {'e'}, {'E'}, {'E'}, {'Ε'}, {'ε'}, {'Е'}, {'Ё'}, {'е'}, {'ё'}, {'∈'}}},
|
||
{[][]rune{{'d'}, {'d'}, {'D'}, {'D'}}},
|
||
{[][]rune{{'c'}, {'c'}, {'C'}, {'С'}, {'с'}, {'C'}, {'℃'}}},
|
||
{[][]rune{{'b'}, {'B'}, {'b'}, {'B'}, {'β'}, {'Β'}, {'В'}, {'в'}, {'ъ'}, {'ь'}, {'♭'}}},
|
||
{[][]rune{{'\''}, {'’'}}},
|
||
{[][]rune{{'a'}, {'A'}, {'a'}, {'A'}, {'α'}, {'@'}, {'@'}, {'а'}, {'Å'}, {'А'}, {'Α'}}},
|
||
{[][]rune{{'"'}, {'”'}}},
|
||
{[][]rune{{'%'}, {'%'}}},
|
||
}
|
||
for _, smcGroup := range smcData {
|
||
for _, smcPair := range smcGroup.charGroup {
|
||
smc.WriteUint16(stringsupport.ToNGWord(string(smcPair[0]))[0])
|
||
if len(smcPair) > 1 {
|
||
smc.WriteUint16(stringsupport.ToNGWord(string(smcPair[1]))[0])
|
||
} else {
|
||
smc.WriteUint16(0)
|
||
}
|
||
}
|
||
smc.WriteUint32(0)
|
||
}
|
||
|
||
filters.WriteUint32(uint32(len(smc.Data())))
|
||
filters.WriteBytes(smc.Data())
|
||
|
||
filters.WriteNullTerminatedBytes([]byte("nam"))
|
||
nam := byteframe.NewByteFrame()
|
||
nam.SetLE()
|
||
for _, word := range namNGWords {
|
||
parts := stringsupport.ToNGWord(word)
|
||
nam.WriteUint32(uint32(len(parts)))
|
||
for _, part := range parts {
|
||
nam.WriteUint16(part)
|
||
nam.WriteInt16(-1) // TODO: figure out how this value relates to corresponding SMC part
|
||
}
|
||
nam.WriteUint16(0)
|
||
nam.WriteInt16(-1)
|
||
}
|
||
filters.WriteUint32(uint32(len(nam.Data())))
|
||
filters.WriteBytes(nam.Data())
|
||
|
||
filters.WriteNullTerminatedBytes([]byte("msg"))
|
||
msg := byteframe.NewByteFrame()
|
||
msg.SetLE()
|
||
for _, word := range msgNGWords {
|
||
parts := stringsupport.ToNGWord(word)
|
||
msg.WriteUint32(uint32(len(parts)))
|
||
for _, part := range parts {
|
||
msg.WriteUint16(part)
|
||
msg.WriteInt16(-1)
|
||
}
|
||
msg.WriteUint16(0)
|
||
msg.WriteInt16(-1)
|
||
}
|
||
filters.WriteUint32(uint32(len(msg.Data())))
|
||
filters.WriteBytes(msg.Data())
|
||
|
||
bf.WriteUint16(uint16(len(filters.Data())))
|
||
bf.WriteBytes(filters.Data())
|
||
|
||
if s.client == VITA || s.client == PS3 || s.client == PS4 {
|
||
var psnUser string
|
||
s.server.db.QueryRow("SELECT psn_id FROM users WHERE id = $1", uid).Scan(&psnUser)
|
||
bf.WriteBytes(stringsupport.PaddedString(psnUser, 20, true))
|
||
}
|
||
|
||
bf.WriteUint16(s.server.erupeConfig.DebugOptions.CapLink.Values[0])
|
||
if s.server.erupeConfig.DebugOptions.CapLink.Values[0] == 51728 {
|
||
bf.WriteUint16(s.server.erupeConfig.DebugOptions.CapLink.Values[1])
|
||
if s.server.erupeConfig.DebugOptions.CapLink.Values[1] == 20000 || s.server.erupeConfig.DebugOptions.CapLink.Values[1] == 20002 {
|
||
ps.Uint16(bf, s.server.erupeConfig.DebugOptions.CapLink.Key, false)
|
||
}
|
||
}
|
||
caStruct := []struct {
|
||
Unk0 uint8
|
||
Unk1 uint32
|
||
Unk2 string
|
||
}{}
|
||
bf.WriteUint8(uint8(len(caStruct)))
|
||
for i := range caStruct {
|
||
bf.WriteUint8(caStruct[i].Unk0)
|
||
bf.WriteUint32(caStruct[i].Unk1)
|
||
ps.Uint8(bf, caStruct[i].Unk2, false)
|
||
}
|
||
bf.WriteUint16(s.server.erupeConfig.DebugOptions.CapLink.Values[2])
|
||
bf.WriteUint16(s.server.erupeConfig.DebugOptions.CapLink.Values[3])
|
||
bf.WriteUint16(s.server.erupeConfig.DebugOptions.CapLink.Values[4])
|
||
if s.server.erupeConfig.DebugOptions.CapLink.Values[2] == 51729 && s.server.erupeConfig.DebugOptions.CapLink.Values[3] == 1 && s.server.erupeConfig.DebugOptions.CapLink.Values[4] == 20000 {
|
||
ps.Uint16(bf, fmt.Sprintf(`%s:%d`, s.server.erupeConfig.DebugOptions.CapLink.Host, s.server.erupeConfig.DebugOptions.CapLink.Port), false)
|
||
}
|
||
|
||
bf.WriteUint32(uint32(s.server.getReturnExpiry(uid).Unix()))
|
||
bf.WriteUint32(0)
|
||
|
||
tickets := []uint32{
|
||
s.server.erupeConfig.GameplayOptions.MezFesSoloTickets,
|
||
s.server.erupeConfig.GameplayOptions.MezFesGroupTickets,
|
||
}
|
||
stalls := []uint8{
|
||
10, 3, 6, 9, 4, 8, 5, 7,
|
||
}
|
||
if s.server.erupeConfig.GameplayOptions.MezFesSwitchMinigame {
|
||
stalls[4] = 2
|
||
}
|
||
|
||
// We can just use the start timestamp as the event ID
|
||
bf.WriteUint32(uint32(channelserver.TimeWeekStart().Unix()))
|
||
// Start time
|
||
bf.WriteUint32(uint32(channelserver.TimeWeekNext().Add(-time.Duration(s.server.erupeConfig.GameplayOptions.MezFesDuration) * time.Second).Unix()))
|
||
// End time
|
||
bf.WriteUint32(uint32(channelserver.TimeWeekNext().Unix()))
|
||
bf.WriteUint8(uint8(len(tickets)))
|
||
for i := range tickets {
|
||
bf.WriteUint32(tickets[i])
|
||
}
|
||
bf.WriteUint8(uint8(len(stalls)))
|
||
for i := range stalls {
|
||
bf.WriteUint8(stalls[i])
|
||
}
|
||
return bf.Data()
|
||
}
|