mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-02-06 10:06:53 +01:00
Merge branch 'main' into feature/diva
# Conflicts: # bundled-schema/DivaShops.sql # bundled-schema/OtherShops.sql # patch-schema/shop-db.sql # server/channelserver/handlers_guild.go # server/channelserver/handlers_tactics.go
This commit is contained in:
@@ -3,6 +3,7 @@ package channelserver
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"erupe-ce/common/mhfcourse"
|
||||
ps "erupe-ce/common/pascalstring"
|
||||
"erupe-ce/common/stringsupport"
|
||||
"fmt"
|
||||
@@ -11,11 +12,11 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"crypto/rand"
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
"go.uber.org/zap"
|
||||
"math/bits"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// Temporary function to just return no results for a MSG_MHF_ENUMERATE* packet
|
||||
@@ -74,23 +75,13 @@ func doAckSimpleFail(s *Session, ackHandle uint32, data []byte) {
|
||||
}
|
||||
|
||||
func updateRights(s *Session) {
|
||||
rightsInt := uint32(0x0E)
|
||||
rightsInt := uint32(2)
|
||||
s.server.db.QueryRow("SELECT rights FROM users u INNER JOIN characters c ON u.id = c.user_id WHERE c.id = $1", s.charID).Scan(&rightsInt)
|
||||
s.courses = mhfpacket.GetCourseStruct(rightsInt)
|
||||
rights := []mhfpacket.ClientRight{{1, 0, 0}}
|
||||
var netcafeBitSet bool
|
||||
for _, course := range s.courses {
|
||||
if (course.ID == 9 || course.ID == 25 || course.ID == 26) && !netcafeBitSet {
|
||||
netcafeBitSet = true
|
||||
rightsInt += 0x40000000 // set netcafe bit
|
||||
rights = append(rights, mhfpacket.ClientRight{ID: 30})
|
||||
}
|
||||
rights = append(rights, mhfpacket.ClientRight{ID: course.ID, Timestamp: 0x70DB59F0})
|
||||
}
|
||||
s.courses, rightsInt = mhfcourse.GetCourseStruct(rightsInt)
|
||||
update := &mhfpacket.MsgSysUpdateRight{
|
||||
ClientRespAckHandle: 0,
|
||||
Bitfield: rightsInt,
|
||||
Rights: rights,
|
||||
Rights: s.courses,
|
||||
UnkSize: 0,
|
||||
}
|
||||
s.QueueSendMHF(update)
|
||||
@@ -221,7 +212,7 @@ func logoutPlayer(s *Session) {
|
||||
timePlayed += sessionTime
|
||||
|
||||
var rpGained int
|
||||
if s.FindCourse("NetCafe").ID != 0 || s.FindCourse("N").ID != 0 {
|
||||
if mhfcourse.CourseExists(30, s.courses) {
|
||||
rpGained = timePlayed / 900
|
||||
timePlayed = timePlayed % 900
|
||||
s.server.db.Exec("UPDATE characters SET cafe_time=cafe_time+$1 WHERE id=$2", sessionTime, s.charID)
|
||||
|
||||
@@ -2,6 +2,7 @@ package channelserver
|
||||
|
||||
import (
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/common/mhfcourse"
|
||||
ps "erupe-ce/common/pascalstring"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
"fmt"
|
||||
@@ -88,7 +89,7 @@ func handleMsgMhfGetCafeDuration(s *Session, p mhfpacket.MHFPacket) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if s.FindCourse("NetCafe").ID != 0 || s.FindCourse("N").ID != 0 {
|
||||
if mhfcourse.CourseExists(30, s.courses) {
|
||||
cafeTime = uint32(TimeAdjusted().Unix()) - uint32(s.sessionStart) + cafeTime
|
||||
}
|
||||
bf.WriteUint32(cafeTime) // Total cafe time
|
||||
|
||||
@@ -3,13 +3,14 @@ package channelserver
|
||||
import (
|
||||
"encoding/hex"
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/common/mhfcourse"
|
||||
"erupe-ce/common/token"
|
||||
"erupe-ce/config"
|
||||
"erupe-ce/network/binpacket"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
"fmt"
|
||||
"golang.org/x/exp/slices"
|
||||
"math"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -81,6 +82,21 @@ func sendServerChatMessage(s *Session, message string) {
|
||||
}
|
||||
|
||||
func parseChatCommand(s *Session, command string) {
|
||||
if strings.HasPrefix(command, commands["PSN"].Prefix) {
|
||||
if commands["PSN"].Enabled {
|
||||
var id string
|
||||
n, err := fmt.Sscanf(command, fmt.Sprintf("%s %%s", commands["PSN"].Prefix), &id)
|
||||
if err != nil || n != 1 {
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandPSNError"], commands["PSN"].Prefix))
|
||||
} else {
|
||||
_, err = s.server.db.Exec(`UPDATE users u SET psn_id=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)`, id, s.charID)
|
||||
if err == nil {
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandPSNSuccess"], id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(command, commands["Reload"].Prefix) {
|
||||
// Flush all objects and users and reload
|
||||
if commands["Reload"].Enabled {
|
||||
@@ -192,13 +208,14 @@ func parseChatCommand(s *Session, command string) {
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseError"], commands["Course"].Prefix))
|
||||
} else {
|
||||
name = strings.ToLower(name)
|
||||
for _, course := range mhfpacket.Courses() {
|
||||
for _, alias := range course.Aliases {
|
||||
for _, course := range mhfcourse.Courses() {
|
||||
for _, alias := range course.Aliases() {
|
||||
if strings.ToLower(name) == strings.ToLower(alias) {
|
||||
if slices.Contains(s.server.erupeConfig.Courses, config.Course{Name: course.Aliases[0], Enabled: true}) {
|
||||
if s.FindCourse(name).ID != 0 {
|
||||
ei := slices.IndexFunc(s.courses, func(c mhfpacket.Course) bool {
|
||||
for _, alias := range c.Aliases {
|
||||
if slices.Contains(s.server.erupeConfig.Courses, config.Course{Name: course.Aliases()[0], Enabled: true}) {
|
||||
var delta, rightsInt uint32
|
||||
if mhfcourse.CourseExists(course.ID, s.courses) {
|
||||
ei := slices.IndexFunc(s.courses, func(c mhfcourse.Course) bool {
|
||||
for _, alias := range c.Aliases() {
|
||||
if strings.ToLower(name) == strings.ToLower(alias) {
|
||||
return true
|
||||
}
|
||||
@@ -206,25 +223,26 @@ func parseChatCommand(s *Session, command string) {
|
||||
return false
|
||||
})
|
||||
if ei != -1 {
|
||||
s.courses = append(s.courses[:ei], s.courses[ei+1:]...)
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseDisabled"], course.Aliases[0]))
|
||||
delta = uint32(-1 * math.Pow(2, float64(course.ID)))
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseDisabled"], course.Aliases()[0]))
|
||||
}
|
||||
} else {
|
||||
s.courses = append(s.courses, course)
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseEnabled"], course.Aliases[0]))
|
||||
delta = uint32(math.Pow(2, float64(course.ID)))
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseEnabled"], course.Aliases()[0]))
|
||||
}
|
||||
var newInt uint32
|
||||
for _, course := range s.courses {
|
||||
newInt += uint32(math.Pow(2, float64(course.ID)))
|
||||
err = s.server.db.QueryRow("SELECT rights FROM users u INNER JOIN characters c ON u.id = c.user_id WHERE c.id = $1", s.charID).Scan(&rightsInt)
|
||||
if err == nil {
|
||||
s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", rightsInt+delta, s.charID)
|
||||
}
|
||||
s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", newInt, s.charID)
|
||||
updateRights(s)
|
||||
} else {
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseLocked"], course.Aliases[0]))
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseLocked"], course.Aliases()[0]))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseError"], commands["Course"].Prefix))
|
||||
}
|
||||
} else {
|
||||
sendDisabledCommandMessage(s, commands["Course"])
|
||||
@@ -367,8 +385,7 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
roll.SetLE()
|
||||
roll.WriteUint16(4) // Unk
|
||||
roll.WriteUint16(authorLen)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
dice := fmt.Sprintf("%d", rand.Intn(100)+1)
|
||||
dice := fmt.Sprintf("%d", token.RNG().Intn(100)+1)
|
||||
roll.WriteUint16(uint16(len(dice) + 1))
|
||||
roll.WriteNullTerminatedBytes([]byte(dice))
|
||||
roll.WriteNullTerminatedBytes(tmp.ReadNullTerminatedBytes())
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
pointerGender = 0x81 // +1
|
||||
pointerGender = 0x51 // +1
|
||||
pointerRP = 0x22D16 // +2
|
||||
pointerHouseTier = 0x1FB6C // +5
|
||||
pointerHouseData = 0x1FE01 // +195
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"erupe-ce/common/stringsupport"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@@ -260,7 +259,7 @@ func dumpSaveData(s *Session, data []byte, suffix string) {
|
||||
func handleMsgMhfLoaddata(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfLoaddata)
|
||||
if _, err := os.Stat(filepath.Join(s.server.erupeConfig.BinPath, "save_override.bin")); err == nil {
|
||||
data, _ := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "save_override.bin"))
|
||||
data, _ := os.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "save_override.bin"))
|
||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package channelserver
|
||||
|
||||
import (
|
||||
"erupe-ce/common/token"
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
@@ -95,9 +95,9 @@ func generateFeatureWeapons(count int) activeFeature {
|
||||
}
|
||||
nums := make([]int, 0)
|
||||
var result int
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
for len(nums) < count {
|
||||
num := r.Intn(14)
|
||||
rng := token.RNG()
|
||||
num := rng.Intn(14)
|
||||
exist := false
|
||||
for _, v := range nums {
|
||||
if v == num {
|
||||
@@ -131,6 +131,7 @@ func handleMsgMhfGetKeepLoginBoostStatus(s *Session, p mhfpacket.MHFPacket) {
|
||||
var loginBoosts []loginBoost
|
||||
rows, err := s.server.db.Queryx("SELECT week_req, expiration, reset FROM login_boost WHERE char_id=$1 ORDER BY week_req", s.charID)
|
||||
if err != nil || s.server.erupeConfig.GameplayOptions.DisableLoginBoost {
|
||||
rows.Close()
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 35))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"encoding/hex"
|
||||
"erupe-ce/common/byteframe"
|
||||
ps "erupe-ce/common/pascalstring"
|
||||
"erupe-ce/common/token"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
@@ -336,8 +336,7 @@ func handleMsgMhfEntryFesta(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
team := uint32(rand.Intn(2))
|
||||
team := uint32(token.RNG().Intn(2))
|
||||
switch team {
|
||||
case 0:
|
||||
s.server.db.Exec("INSERT INTO festa_registrations VALUES ($1, 'blue')", guild.ID)
|
||||
|
||||
@@ -1060,7 +1060,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) {
|
||||
uint32 guild id
|
||||
uint32 guild leader id (for mail)
|
||||
uint32 unk (always null in pcap)
|
||||
uint16 unk (always 0001 in pcap)
|
||||
uint16 member count
|
||||
uint16 len guild name
|
||||
string nullterm guild name
|
||||
uint16 len guild leader name
|
||||
@@ -1862,7 +1862,6 @@ func handleMsgMhfEnumerateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfUpdateGuildMessageBoard)
|
||||
bf := byteframe.NewByteFrameFromBytes(pkt.Request)
|
||||
guild, err := GetGuildInfoByCharacterId(s, s.charID)
|
||||
applicant := false
|
||||
if guild != nil {
|
||||
@@ -1874,45 +1873,26 @@ func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
switch pkt.MessageOp {
|
||||
case 0: // Create message
|
||||
postType := bf.ReadUint32() // 0 = message, 1 = news
|
||||
stampID := bf.ReadUint32()
|
||||
titleLength := bf.ReadUint32()
|
||||
bodyLength := bf.ReadUint32()
|
||||
title := stringsupport.SJISToUTF8(bf.ReadBytes(uint(titleLength)))
|
||||
body := stringsupport.SJISToUTF8(bf.ReadBytes(uint(bodyLength)))
|
||||
s.server.db.Exec("INSERT INTO guild_posts (guild_id, author_id, stamp_id, post_type, title, body) VALUES ($1, $2, $3, $4, $5, $6)", guild.ID, s.charID, stampID, postType, title, body)
|
||||
s.server.db.Exec("INSERT INTO guild_posts (guild_id, author_id, stamp_id, post_type, title, body) VALUES ($1, $2, $3, $4, $5, $6)", guild.ID, s.charID, pkt.StampID, pkt.PostType, pkt.Title, pkt.Body)
|
||||
// TODO: if there are too many messages, purge excess
|
||||
case 1: // Delete message
|
||||
postID := bf.ReadUint32()
|
||||
s.server.db.Exec("DELETE FROM guild_posts WHERE id = $1", postID)
|
||||
s.server.db.Exec("DELETE FROM guild_posts WHERE id = $1", pkt.PostID)
|
||||
case 2: // Update message
|
||||
postID := bf.ReadUint32()
|
||||
bf.ReadBytes(8)
|
||||
titleLength := bf.ReadUint32()
|
||||
bodyLength := bf.ReadUint32()
|
||||
title := stringsupport.SJISToUTF8(bf.ReadBytes(uint(titleLength)))
|
||||
body := stringsupport.SJISToUTF8(bf.ReadBytes(uint(bodyLength)))
|
||||
s.server.db.Exec("UPDATE guild_posts SET title = $1, body = $2 WHERE id = $3", title, body, postID)
|
||||
s.server.db.Exec("UPDATE guild_posts SET title = $1, body = $2 WHERE id = $3", pkt.Title, pkt.Body, pkt.PostID)
|
||||
case 3: // Update stamp
|
||||
postID := bf.ReadUint32()
|
||||
bf.ReadBytes(8)
|
||||
stampID := bf.ReadUint32()
|
||||
s.server.db.Exec("UPDATE guild_posts SET stamp_id = $1 WHERE id = $2", stampID, postID)
|
||||
s.server.db.Exec("UPDATE guild_posts SET stamp_id = $1 WHERE id = $2", pkt.StampID, pkt.PostID)
|
||||
case 4: // Like message
|
||||
postID := bf.ReadUint32()
|
||||
bf.ReadBytes(8)
|
||||
likeState := bf.ReadBool()
|
||||
var likedBy string
|
||||
err := s.server.db.QueryRow("SELECT liked_by FROM guild_posts WHERE id = $1", postID).Scan(&likedBy)
|
||||
err := s.server.db.QueryRow("SELECT liked_by FROM guild_posts WHERE id = $1", pkt.PostID).Scan(&likedBy)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get guild message like data from db", zap.Error(err))
|
||||
} else {
|
||||
if likeState {
|
||||
if pkt.LikeState {
|
||||
likedBy = stringsupport.CSVAdd(likedBy, int(s.charID))
|
||||
s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE id = $2", likedBy, postID)
|
||||
s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE id = $2", likedBy, pkt.PostID)
|
||||
} else {
|
||||
likedBy = stringsupport.CSVRemove(likedBy, int(s.charID))
|
||||
s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE id = $2", likedBy, postID)
|
||||
s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE id = $2", likedBy, pkt.PostID)
|
||||
}
|
||||
}
|
||||
case 5: // Check for new messages
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package channelserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/common/stringsupport"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
)
|
||||
|
||||
func handleMsgMhfPostGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
||||
@@ -206,7 +204,7 @@ func handleMsgMhfGetGuildScoutList(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
|
||||
rows, err := s.server.db.Queryx(`
|
||||
SELECT c.id, c.name, ga.actor_id
|
||||
SELECT c.id, c.name, c.hrp, c.gr, ga.actor_id
|
||||
FROM guild_applications ga
|
||||
JOIN characters c ON c.id = ga.character_id
|
||||
WHERE ga.guild_id = $1 AND ga.application_type = 'invited'
|
||||
@@ -231,14 +229,14 @@ func handleMsgMhfGetGuildScoutList(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
for rows.Next() {
|
||||
var charName string
|
||||
var charID uint32
|
||||
var actorID uint32
|
||||
var charID, actorID uint32
|
||||
var hrp, gr uint16
|
||||
|
||||
err = rows.Scan(&charID, &charName, &actorID)
|
||||
err = rows.Scan(&charID, &charName, &hrp, &gr, &actorID)
|
||||
|
||||
if err != nil {
|
||||
doAckSimpleFail(s, pkt.AckHandle, nil)
|
||||
panic(err)
|
||||
continue
|
||||
}
|
||||
|
||||
// This seems to be used as a unique ID for the invitation sent
|
||||
@@ -247,14 +245,10 @@ func handleMsgMhfGetGuildScoutList(s *Session, p mhfpacket.MHFPacket) {
|
||||
bf.WriteUint32(charID)
|
||||
bf.WriteUint32(actorID)
|
||||
bf.WriteUint32(charID)
|
||||
bf.WriteUint32(uint32(time.Now().Unix()))
|
||||
bf.WriteUint16(0x00) // HR?
|
||||
bf.WriteUint16(0x00) // GR?
|
||||
|
||||
charNameBytes, _ := stringsupport.ConvertUTF8ToShiftJIS(charName)
|
||||
|
||||
bf.WriteBytes(charNameBytes)
|
||||
bf.WriteBytes(make([]byte, 32-len(charNameBytes))) // Fixed length string
|
||||
bf.WriteUint32(uint32(TimeAdjusted().Unix()))
|
||||
bf.WriteUint16(hrp) // HR?
|
||||
bf.WriteUint16(gr) // GR?
|
||||
bf.WriteBytes(stringsupport.PaddedString(charName, 32, true))
|
||||
count++
|
||||
}
|
||||
|
||||
|
||||
@@ -326,15 +326,8 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) {
|
||||
flags |= 0x04
|
||||
}
|
||||
|
||||
// Workaround until EN mail items are patched
|
||||
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.DisableMailItems {
|
||||
if itemAttached {
|
||||
flags |= 0x08
|
||||
}
|
||||
} else {
|
||||
if m.AttachedItemReceived {
|
||||
flags |= 0x08
|
||||
}
|
||||
if m.AttachedItemReceived {
|
||||
flags |= 0x08
|
||||
}
|
||||
|
||||
if m.IsGuildInvite {
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"erupe-ce/server/channelserver/compression/nullcomp"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@@ -292,7 +291,7 @@ func handleMsgMhfEnumerateAiroulist(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfEnumerateAiroulist)
|
||||
resp := byteframe.NewByteFrame()
|
||||
if _, err := os.Stat(filepath.Join(s.server.erupeConfig.BinPath, "airoulist.bin")); err == nil {
|
||||
data, _ := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "airoulist.bin"))
|
||||
data, _ := os.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "airoulist.bin"))
|
||||
resp.WriteBytes(data)
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
ps "erupe-ce/common/pascalstring"
|
||||
"fmt"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
@@ -92,7 +92,7 @@ func handleMsgMhfLoadRengokuData(s *Session, p mhfpacket.MHFPacket) {
|
||||
func handleMsgMhfGetRengokuBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfGetRengokuBinary)
|
||||
// a (massively out of date) version resides in the game's /dat/ folder or up to date can be pulled from packets
|
||||
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "rengoku_data.bin"))
|
||||
data, err := os.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "rengoku_data.bin"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -358,6 +358,9 @@ func getRandomEntries(entries []GachaEntry, rolls int, isBox bool) ([]GachaEntry
|
||||
totalWeight += entries[i].Weight
|
||||
}
|
||||
for {
|
||||
if rolls == len(chosen) {
|
||||
break
|
||||
}
|
||||
if !isBox {
|
||||
result := rand.Float64() * totalWeight
|
||||
for _, entry := range entries {
|
||||
@@ -373,9 +376,6 @@ func getRandomEntries(entries []GachaEntry, rolls int, isBox bool) ([]GachaEntry
|
||||
entries[result] = entries[len(entries)-1]
|
||||
entries = entries[:len(entries)-1]
|
||||
}
|
||||
if rolls == len(chosen) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return chosen, nil
|
||||
}
|
||||
|
||||
@@ -57,6 +57,8 @@ func getLangStrings(s *Server) map[string]string {
|
||||
strings["commandCourseLocked"] = "%sコースはロックされています"
|
||||
strings["commandTeleportError"] = "テレポートコマンドエラー 構文:%s x y"
|
||||
strings["commandTeleportSuccess"] = "%d %dにテレポート"
|
||||
strings["commandPSNError"] = "PSN連携コマンドエラー 例:%s <psn id>"
|
||||
strings["commandPSNSuccess"] = "PSN「%s」が連携されています"
|
||||
|
||||
strings["commandRaviNoCommand"] = "ラヴィコマンドが指定されていません"
|
||||
strings["commandRaviStartSuccess"] = "大討伐を開始します"
|
||||
@@ -142,6 +144,8 @@ func getLangStrings(s *Server) map[string]string {
|
||||
strings["commandCourseLocked"] = "%s Course is locked"
|
||||
strings["commandTeleportError"] = "Error in command. Format: %s x y"
|
||||
strings["commandTeleportSuccess"] = "Teleporting to %d %d"
|
||||
strings["commandPSNError"] = "Error in command. Format: %s <psn id>"
|
||||
strings["commandPSNSuccess"] = "Connected PSN ID: %s"
|
||||
|
||||
strings["commandRaviNoCommand"] = "No Raviente command specified!"
|
||||
strings["commandRaviStartSuccess"] = "The Great Slaying will begin in a moment"
|
||||
|
||||
@@ -3,10 +3,10 @@ package channelserver
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"erupe-ce/common/mhfcourse"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -32,6 +32,7 @@ type Session struct {
|
||||
cryptConn *network.CryptConn
|
||||
sendPackets chan packet
|
||||
clientContext *clientctx.ClientContext
|
||||
lastPacket time.Time
|
||||
|
||||
userEnteredStage bool // If the user has entered a stage before
|
||||
stageID string
|
||||
@@ -42,7 +43,7 @@ type Session struct {
|
||||
charID uint32
|
||||
logKey []byte
|
||||
sessionStart int64
|
||||
courses []mhfpacket.Course
|
||||
courses []mhfcourse.Course
|
||||
token string
|
||||
kqf []byte
|
||||
kqfOverride bool
|
||||
@@ -73,6 +74,7 @@ func NewSession(server *Server, conn net.Conn) *Session {
|
||||
cryptConn: network.NewCryptConn(conn),
|
||||
sendPackets: make(chan packet, 20),
|
||||
clientContext: &clientctx.ClientContext{}, // Unused
|
||||
lastPacket: time.Now(),
|
||||
sessionStart: TimeAdjusted().Unix(),
|
||||
stageMoveStack: stringstack.New(),
|
||||
}
|
||||
@@ -160,6 +162,10 @@ func (s *Session) sendLoop() {
|
||||
|
||||
func (s *Session) recvLoop() {
|
||||
for {
|
||||
if time.Now().Add(-30 * time.Second).After(s.lastPacket) {
|
||||
logoutPlayer(s)
|
||||
return
|
||||
}
|
||||
if s.closed {
|
||||
logoutPlayer(s)
|
||||
return
|
||||
@@ -181,6 +187,7 @@ func (s *Session) recvLoop() {
|
||||
}
|
||||
|
||||
func (s *Session) handlePacketGroup(pktGroup []byte) {
|
||||
s.lastPacket = time.Now()
|
||||
bf := byteframe.NewByteFrameFromBytes(pktGroup)
|
||||
opcodeUint16 := bf.ReadUint16()
|
||||
opcode := network.PacketID(opcodeUint16)
|
||||
@@ -228,7 +235,6 @@ func ignored(opcode network.PacketID) bool {
|
||||
network.MSG_SYS_TIME,
|
||||
network.MSG_SYS_EXTEND_THRESHOLD,
|
||||
network.MSG_SYS_POSITION_OBJECT,
|
||||
network.MSG_MHF_ENUMERATE_QUEST,
|
||||
network.MSG_MHF_SAVEDATA,
|
||||
}
|
||||
set := make(map[network.PacketID]struct{}, len(ignoreList))
|
||||
@@ -262,14 +268,3 @@ func (s *Session) logMessage(opcode uint16, data []byte, sender string, recipien
|
||||
fmt.Printf("Data [%d bytes]:\n(Too long!)\n\n", len(data))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) FindCourse(name string) mhfpacket.Course {
|
||||
for _, course := range s.courses {
|
||||
for _, alias := range course.Aliases {
|
||||
if strings.ToLower(name) == strings.ToLower(alias) {
|
||||
return course
|
||||
}
|
||||
}
|
||||
}
|
||||
return mhfpacket.Course{}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ package channelserver
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"time"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
)
|
||||
@@ -49,7 +47,6 @@ type Stage struct {
|
||||
host *Session
|
||||
maxPlayers uint16
|
||||
password string
|
||||
createdAt string
|
||||
}
|
||||
|
||||
// NewStage creates a new stage with intialized values.
|
||||
@@ -62,7 +59,6 @@ func NewStage(ID string) *Stage {
|
||||
objectIndex: 0,
|
||||
rawBinaryData: make(map[stageBinaryKey][]byte),
|
||||
maxPlayers: 4,
|
||||
createdAt: time.Now().Format("01-02-2006 15:04:05"),
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user