diff --git a/common/stringsupport/string_convert.go b/common/stringsupport/string_convert.go index de4d04364..96c14c9ba 100644 --- a/common/stringsupport/string_convert.go +++ b/common/stringsupport/string_convert.go @@ -29,6 +29,23 @@ func SJISToUTF8(b []byte) string { return string(result) } +func ToNGWord(x string) []uint16 { + var w []uint16 + for _, r := range []rune(x) { + if r > 0xFF { + t := UTF8ToSJIS(string(r)) + if len(t) > 1 { + w = append(w, uint16(t[1])<<8|uint16(t[0])) + } else { + w = append(w, uint16(t[0])) + } + } else { + w = append(w, uint16(r)) + } + } + return w +} + func PaddedString(x string, size uint, t bool) []byte { if t { e := japanese.ShiftJIS.NewEncoder() diff --git a/network/mhfpacket/msg_mhf_stampcard_stamp.go b/network/mhfpacket/msg_mhf_stampcard_stamp.go index a783b3e91..281134c9d 100644 --- a/network/mhfpacket/msg_mhf_stampcard_stamp.go +++ b/network/mhfpacket/msg_mhf_stampcard_stamp.go @@ -37,13 +37,16 @@ func (m *MsgMhfStampcardStamp) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli } m.Stamps = bf.ReadUint16() bf.ReadUint16() // Zeroed - if _config.ErupeConfig.RealClientMode > _config.Z1 { + if _config.ErupeConfig.RealClientMode >= _config.Z2 { m.Reward1 = uint16(bf.ReadUint32()) m.Reward2 = uint16(bf.ReadUint32()) m.Item1 = uint16(bf.ReadUint32()) m.Item2 = uint16(bf.ReadUint32()) m.Quantity1 = uint16(bf.ReadUint32()) m.Quantity2 = uint16(bf.ReadUint32()) + } else { + m.Reward1 = 10 + m.Reward2 = 10 } return nil } diff --git a/network/mhfpacket/msg_sys_terminal_log.go b/network/mhfpacket/msg_sys_terminal_log.go index 5033346b4..bad160a73 100644 --- a/network/mhfpacket/msg_sys_terminal_log.go +++ b/network/mhfpacket/msg_sys_terminal_log.go @@ -40,8 +40,8 @@ func (m *MsgSysTerminalLog) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Client entryCount := int(bf.ReadUint16()) bf.ReadUint16() // Zeroed - var e TerminalLogEntry for i := 0; i < entryCount; i++ { + var e TerminalLogEntry e.Index = bf.ReadUint32() e.Type1 = bf.ReadUint8() e.Type2 = bf.ReadUint8() diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index d301ad6c9..4f8e89e7c 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -1051,32 +1051,58 @@ func handleMsgMhfUpdateEtcPoint(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfStampcardStamp(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfStampcardStamp) + + rewards := []struct { + HR uint16 + Item1 uint16 + Quantity1 uint16 + Item2 uint16 + Quantity2 uint16 + }{ + {0, 6164, 1, 6164, 2}, + {50, 6164, 2, 6164, 3}, + {100, 6164, 3, 5392, 1}, + {300, 5392, 1, 5392, 3}, + {999, 5392, 1, 5392, 4}, + } + if _config.ErupeConfig.RealClientMode <= _config.Z1 { + for _, reward := range rewards { + if pkt.HR >= reward.HR { + pkt.Item1 = reward.Item1 + pkt.Quantity1 = reward.Quantity1 + pkt.Item2 = reward.Item2 + pkt.Quantity2 = reward.Quantity2 + } + } + } + bf := byteframe.NewByteFrame() bf.WriteUint16(pkt.HR) - var stamps uint16 - _ = s.server.db.QueryRow(`SELECT stampcard FROM characters WHERE id = $1`, s.charID).Scan(&stamps) if _config.ErupeConfig.RealClientMode >= _config.G1 { bf.WriteUint16(pkt.GR) } + var stamps, rewardTier, rewardUnk uint16 + reward := mhfitem.MHFItemStack{Item: mhfitem.MHFItem{}} + s.server.db.QueryRow(`UPDATE characters SET stampcard = stampcard + $1 WHERE id = $2 RETURNING stampcard`, pkt.Stamps, s.charID).Scan(&stamps) + bf.WriteUint16(stamps - pkt.Stamps) bf.WriteUint16(stamps) - stamps += pkt.Stamps - bf.WriteUint16(stamps) - s.server.db.Exec(`UPDATE characters SET stampcard = $1 WHERE id = $2`, stamps, s.charID) - if stamps%30 == 0 { - bf.WriteUint16(2) - bf.WriteUint16(pkt.Reward2) - bf.WriteUint16(pkt.Item2) - bf.WriteUint16(pkt.Quantity2) - addWarehouseItem(s, mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: pkt.Item2}, Quantity: pkt.Quantity2}) - } else if stamps%15 == 0 { - bf.WriteUint16(1) - bf.WriteUint16(pkt.Reward1) - bf.WriteUint16(pkt.Item1) - bf.WriteUint16(pkt.Quantity1) - addWarehouseItem(s, mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: pkt.Item1}, Quantity: pkt.Quantity1}) - } else { - bf.WriteBytes(make([]byte, 8)) + + if stamps/30 > (stamps-pkt.Stamps)/30 { + rewardTier = 2 + rewardUnk = pkt.Reward2 + reward = mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: pkt.Item2}, Quantity: pkt.Quantity2} + addWarehouseItem(s, reward) + } else if stamps/15 > (stamps-pkt.Stamps)/15 { + rewardTier = 1 + rewardUnk = pkt.Reward1 + reward = mhfitem.MHFItemStack{Item: mhfitem.MHFItem{ItemID: pkt.Item1}, Quantity: pkt.Quantity1} + addWarehouseItem(s, reward) } + + bf.WriteUint16(rewardTier) + bf.WriteUint16(rewardUnk) + bf.WriteUint16(reward.Item.ItemID) + bf.WriteUint16(reward.Quantity) doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } diff --git a/server/channelserver/handlers_cafe.go b/server/channelserver/handlers_cafe.go index b87bac5ff..406732371 100644 --- a/server/channelserver/handlers_cafe.go +++ b/server/channelserver/handlers_cafe.go @@ -4,6 +4,7 @@ import ( "erupe-ce/common/byteframe" "erupe-ce/common/mhfcourse" ps "erupe-ce/common/pascalstring" + _config "erupe-ce/config" "erupe-ce/network/mhfpacket" "fmt" "go.uber.org/zap" @@ -92,10 +93,11 @@ func handleMsgMhfGetCafeDuration(s *Session, p mhfpacket.MHFPacket) { if mhfcourse.CourseExists(30, s.courses) { cafeTime = uint32(TimeAdjusted().Unix()) - uint32(s.sessionStart) + cafeTime } - bf.WriteUint32(cafeTime) // Total cafe time - bf.WriteUint16(0) - ps.Uint16(bf, fmt.Sprintf(s.server.i18n.cafe.reset, int(cafeReset.Month()), cafeReset.Day()), true) - + bf.WriteUint32(cafeTime) + if _config.ErupeConfig.RealClientMode >= _config.ZZ { + bf.WriteUint16(0) + ps.Uint16(bf, fmt.Sprintf(s.server.i18n.cafe.reset, int(cafeReset.Month()), cafeReset.Day()), true) + } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index 5e47d0436..c91660b54 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -367,13 +367,17 @@ func handleMsgMhfAcquireTitle(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfResetTitle(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfOperateWarehouse) +func initializeWarehouse(s *Session) { var t int err := s.server.db.QueryRow("SELECT character_id FROM warehouse WHERE character_id=$1", s.charID).Scan(&t) if err != nil { s.server.db.Exec("INSERT INTO warehouse (character_id) VALUES ($1)", s.charID) } +} + +func handleMsgMhfOperateWarehouse(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfOperateWarehouse) + initializeWarehouse(s) bf := byteframe.NewByteFrame() bf.WriteUint8(pkt.Operation) switch pkt.Operation { @@ -446,6 +450,7 @@ func addWarehouseEquipment(s *Session, equipment mhfitem.MHFEquipment) { } func warehouseGetItems(s *Session, index uint8) []mhfitem.MHFItemStack { + initializeWarehouse(s) var data []byte var items []mhfitem.MHFItemStack s.server.db.QueryRow(fmt.Sprintf(`SELECT item%d FROM warehouse WHERE character_id=$1`, index), s.charID).Scan(&data) diff --git a/server/signserver/dsgn_resp.go b/server/signserver/dsgn_resp.go index 250bdae46..3d102d52c 100644 --- a/server/signserver/dsgn_resp.go +++ b/server/signserver/dsgn_resp.go @@ -135,7 +135,203 @@ func (s *Session) makeSignResponse(uid uint32) []byte { bf.WriteUint32(s.server.getLastCID(uid)) bf.WriteUint32(s.server.getUserRights(uid)) - ps.Uint16(bf, "", false) // filters + + namNGWords := []string{} + msgNGWords := []string{} + + 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) + var i int16 + j := int16(-1) + for _, smcGroup := range smcData { + if rune(part) == rune(stringsupport.ToNGWord(string(smcGroup.charGroup[0][0]))[0]) { + j = i + break + } + i += int16(len(smcGroup.charGroup) + 1) + } + nam.WriteInt16(j) + } + 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) + var i int16 + j := int16(-1) + for _, smcGroup := range smcData { + if rune(part) == rune(stringsupport.ToNGWord(string(smcGroup.charGroup[0][0]))[0]) { + j = i + break + } + i += int16(len(smcGroup.charGroup) + 1) + } + msg.WriteInt16(j) + } + 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)