mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-02-06 01:57:38 +01:00
Merge branch 'main' into feature/diva
# Conflicts: # server/channelserver/handlers_quest.go
This commit is contained in:
@@ -77,7 +77,13 @@ func updateRights(s *Session) {
|
||||
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 == 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})
|
||||
}
|
||||
update := &mhfpacket.MsgSysUpdateRight{
|
||||
@@ -135,6 +141,7 @@ func handleMsgSysLogin(s *Session, p mhfpacket.MHFPacket) {
|
||||
s.charID = pkt.CharID0
|
||||
s.token = pkt.LoginTokenString
|
||||
s.Unlock()
|
||||
|
||||
updateRights(s)
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint32(uint32(Time_Current_Adjusted().Unix())) // Unix timestamp
|
||||
@@ -213,16 +220,16 @@ func logoutPlayer(s *Session) {
|
||||
timePlayed += sessionTime
|
||||
|
||||
var rpGained int
|
||||
if s.FindCourse("Netcafe").ID != 0 {
|
||||
if s.FindCourse("NetCafe").ID != 0 || s.FindCourse("N").ID != 0 {
|
||||
rpGained = timePlayed / 900
|
||||
timePlayed = timePlayed % 900
|
||||
s.server.db.Exec("UPDATE characters SET cafe_time=cafe_time+$1 WHERE id=$2", sessionTime, s.charID)
|
||||
} else {
|
||||
rpGained = timePlayed / 1800
|
||||
timePlayed = timePlayed % 1800
|
||||
}
|
||||
|
||||
s.server.db.Exec("UPDATE characters SET time_played = $1 WHERE id = $2", timePlayed, s.charID)
|
||||
s.server.db.Exec("UPDATE characters SET cafe_time=cafe_time+$1 WHERE id=$2", sessionTime, s.charID)
|
||||
|
||||
treasureHuntUnregister(s)
|
||||
|
||||
@@ -1489,10 +1496,6 @@ func handleMsgMhfInfoScenarioCounter(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfGetBbsSnsStatus(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
func handleMsgMhfApplyBbsArticle(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
func handleMsgMhfGetEtcPoints(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfGetEtcPoints)
|
||||
|
||||
|
||||
41
server/channelserver/handlers_bbs.go
Normal file
41
server/channelserver/handlers_bbs.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package channelserver
|
||||
|
||||
import (
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/common/stringsupport"
|
||||
"erupe-ce/common/token"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
)
|
||||
|
||||
func handleMsgMhfGetBbsUserStatus(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfGetBbsUserStatus)
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint32(200)
|
||||
bf.WriteUint32(0)
|
||||
bf.WriteUint32(0)
|
||||
bf.WriteUint32(0)
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfGetBbsSnsStatus(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfGetBbsSnsStatus)
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint32(200)
|
||||
bf.WriteUint32(401)
|
||||
bf.WriteUint32(401)
|
||||
bf.WriteUint32(0)
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfApplyBbsArticle(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfApplyBbsArticle)
|
||||
bf := byteframe.NewByteFrame()
|
||||
articleToken := token.Generate(40)
|
||||
bf.WriteUint32(200)
|
||||
bf.WriteUint32(80)
|
||||
bf.WriteUint32(0)
|
||||
bf.WriteUint32(0)
|
||||
bf.WriteBytes(stringsupport.PaddedString(articleToken, 64, false))
|
||||
bf.WriteBytes(stringsupport.PaddedString(s.server.erupeConfig.ScreenshotAPIURL, 64, false))
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
@@ -74,9 +74,14 @@ func handleMsgMhfGetCafeDuration(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
var cafeReset time.Time
|
||||
err := s.server.db.QueryRow(`SELECT cafe_reset FROM characters WHERE id=$1`, s.charID).Scan(&cafeReset)
|
||||
if err != nil {
|
||||
cafeReset = TimeWeekNext()
|
||||
s.server.db.Exec(`UPDATE characters SET cafe_reset=$1 WHERE id=$2`, cafeReset, s.charID)
|
||||
}
|
||||
if Time_Current_Adjusted().After(cafeReset) {
|
||||
cafeReset = TimeWeekNext()
|
||||
s.server.db.Exec(`UPDATE characters SET cafe_time=0, cafe_reset=$1 WHERE id=$2; DELETE FROM cafe_accepted WHERE character_id=$2`, cafeReset, s.charID)
|
||||
s.server.db.Exec(`UPDATE characters SET cafe_time=0, cafe_reset=$1 WHERE id=$2`, cafeReset, s.charID)
|
||||
s.server.db.Exec(`DELETE FROM cafe_accepted WHERE character_id=$1`, s.charID)
|
||||
}
|
||||
|
||||
var cafeTime uint32
|
||||
@@ -84,10 +89,13 @@ func handleMsgMhfGetCafeDuration(s *Session, p mhfpacket.MHFPacket) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cafeTime = uint32(Time_Current_Adjusted().Unix()) - uint32(s.sessionStart) + cafeTime
|
||||
if s.FindCourse("NetCafe").ID != 0 || s.FindCourse("N").ID != 0 {
|
||||
cafeTime = uint32(Time_Current_Adjusted().Unix()) - uint32(s.sessionStart) + cafeTime
|
||||
}
|
||||
bf.WriteUint32(cafeTime) // Total cafe time
|
||||
bf.WriteUint16(0)
|
||||
ps.Uint16(bf, fmt.Sprintf("Resets on %s %d", cafeReset.Month().String(), cafeReset.Day()), true)
|
||||
ps.Uint16(bf, fmt.Sprintf(s.server.dict["cafeReset"], int(cafeReset.Month()), cafeReset.Day()), true)
|
||||
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
|
||||
@@ -324,7 +324,7 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
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).Value != 0 {
|
||||
if s.FindCourse(name).ID != 0 {
|
||||
ei := slices.IndexFunc(s.courses, func(c mhfpacket.Course) bool {
|
||||
for _, alias := range c.Aliases {
|
||||
if strings.ToLower(name) == strings.ToLower(alias) {
|
||||
@@ -335,20 +335,20 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
})
|
||||
if ei != -1 {
|
||||
s.courses = append(s.courses[:ei], s.courses[ei+1:]...)
|
||||
sendServerChatMessage(s, fmt.Sprintf(`%s Course disabled.`, course.Aliases[0]))
|
||||
sendServerChatMessage(s, fmt.Sprintf(`%s Course disabled`, course.Aliases[0]))
|
||||
}
|
||||
} else {
|
||||
s.courses = append(s.courses, course)
|
||||
sendServerChatMessage(s, fmt.Sprintf(`%s Course enabled.`, course.Aliases[0]))
|
||||
sendServerChatMessage(s, fmt.Sprintf(`%s Course enabled`, course.Aliases[0]))
|
||||
}
|
||||
var newInt uint32
|
||||
for _, course := range s.courses {
|
||||
newInt += course.Value
|
||||
newInt += uint32(math.Pow(2, float64(course.ID)))
|
||||
}
|
||||
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 Course is locked.`, course.Aliases[0]))
|
||||
sendServerChatMessage(s, fmt.Sprintf(`%s Course is locked`, course.Aliases[0]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2005,6 +2005,7 @@ func handleMsgMhfCheckMonthlyItem(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfCheckMonthlyItem)
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x01})
|
||||
// TODO: Implement month-by-month tracker, 0 = Not claimed, 1 = Claimed
|
||||
// Also handles HLC and EXC items, IDs = 064D, 076B
|
||||
}
|
||||
|
||||
func handleMsgMhfAcquireMonthlyItem(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
@@ -62,10 +62,9 @@ func handleMsgMhfPostGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
||||
mail := &Mail{
|
||||
SenderID: s.charID,
|
||||
RecipientID: pkt.CharID,
|
||||
Subject: "Invitation!",
|
||||
Subject: s.server.dict["guildInviteName"],
|
||||
Body: fmt.Sprintf(
|
||||
"%s has invited you to join 「%s」\nDo you want to accept?",
|
||||
getCharacterName(s, s.charID),
|
||||
s.server.dict["guildInvite"],
|
||||
guildInfo.Name,
|
||||
),
|
||||
IsGuildInvite: true,
|
||||
@@ -149,30 +148,30 @@ func handleMsgMhfAnswerGuildScout(s *Session, p mhfpacket.MHFPacket) {
|
||||
err = guild.AcceptApplication(s, s.charID)
|
||||
mail = append(mail, Mail{
|
||||
RecipientID: s.charID,
|
||||
Subject: "Success!",
|
||||
Body: fmt.Sprintf("You successfully joined 「%s」.", guild.Name),
|
||||
Subject: s.server.dict["guildInviteSuccessName"],
|
||||
Body: fmt.Sprintf(s.server.dict["guildInviteSuccess"], guild.Name),
|
||||
IsSystemMessage: true,
|
||||
})
|
||||
mail = append(mail, Mail{
|
||||
SenderID: s.charID,
|
||||
RecipientID: pkt.LeaderID,
|
||||
Subject: "Accepted",
|
||||
Body: fmt.Sprintf("%s accepted your invitation to join 「%s」.", s.Name, guild.Name),
|
||||
Subject: s.server.dict["guildInviteAcceptedName"],
|
||||
Body: fmt.Sprintf(s.server.dict["guildInviteAccepted"], guild.Name),
|
||||
IsSystemMessage: true,
|
||||
})
|
||||
} else {
|
||||
err = guild.RejectApplication(s, s.charID)
|
||||
mail = append(mail, Mail{
|
||||
RecipientID: s.charID,
|
||||
Subject: "Declined",
|
||||
Body: fmt.Sprintf("You declined the invitation to join 「%s」.", guild.Name),
|
||||
Subject: s.server.dict["guildInviteRejectName"],
|
||||
Body: fmt.Sprintf(s.server.dict["guildInviteReject"], guild.Name),
|
||||
IsSystemMessage: true,
|
||||
})
|
||||
mail = append(mail, Mail{
|
||||
SenderID: s.charID,
|
||||
RecipientID: pkt.LeaderID,
|
||||
Subject: "Declined",
|
||||
Body: fmt.Sprintf("%s declined your invitation to join 「%s」.", s.Name, guild.Name),
|
||||
Subject: s.server.dict["guildInviteDeclined"],
|
||||
Body: fmt.Sprintf(s.server.dict["guildInviteDeclined"], guild.Name),
|
||||
IsSystemMessage: true,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package channelserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
@@ -54,5 +54,3 @@ func handleMsgSysGetUserBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
|
||||
func handleMsgSysNotifyUserBinary(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
func handleMsgMhfGetBbsUserStatus(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
@@ -52,6 +52,9 @@ type Server struct {
|
||||
stagesLock sync.RWMutex
|
||||
stages map[string]*Stage
|
||||
|
||||
// Used to map different languages
|
||||
dict map[string]string
|
||||
|
||||
// UserBinary
|
||||
userBinaryPartsLock sync.RWMutex
|
||||
userBinaryParts map[userBinaryPartID][]byte
|
||||
@@ -164,6 +167,8 @@ func NewServer(config *Config) *Server {
|
||||
// MezFes
|
||||
s.stages["sl1Ns462p0a0u0"] = NewStage("sl1Ns462p0a0u0")
|
||||
|
||||
s.dict = getLangStrings(s)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -279,6 +284,7 @@ func (s *Server) WorldcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session,
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint16(uint16(pkt.Opcode()))
|
||||
pkt.Build(bf, session.clientContext)
|
||||
bf.WriteUint16(0x0010)
|
||||
session.QueueSendNonBlocking(bf.Data())
|
||||
}
|
||||
}
|
||||
@@ -313,15 +319,17 @@ func (s *Server) BroadcastRaviente(ip uint32, port uint16, stage []byte, _type u
|
||||
var text string
|
||||
switch _type {
|
||||
case 2:
|
||||
text = "<Great Slaying: Berserk> is being held!"
|
||||
text = s.dict["ravienteBerserk"]
|
||||
case 3:
|
||||
text = s.dict["ravienteExtreme"]
|
||||
case 4:
|
||||
text = "<Great Slaying: Extreme> is being held!"
|
||||
text = s.dict["ravienteExtremeLimited"]
|
||||
case 5:
|
||||
text = "<Great Slaying: Berserk Practice> is being held!"
|
||||
text = s.dict["ravienteBerserkSmall"]
|
||||
default:
|
||||
s.logger.Error("Unk raviente type", zap.Uint8("_type", _type))
|
||||
}
|
||||
ps.Uint16(bf, text, false)
|
||||
ps.Uint16(bf, text, true)
|
||||
bf.WriteBytes([]byte{0x5F, 0x53, 0x00})
|
||||
bf.WriteUint32(ip) // IP address
|
||||
bf.WriteUint16(port) // Port
|
||||
|
||||
52
server/channelserver/sys_language.go
Normal file
52
server/channelserver/sys_language.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package channelserver
|
||||
|
||||
func getLangStrings(s *Server) map[string]string {
|
||||
strings := make(map[string]string)
|
||||
switch s.erupeConfig.Language {
|
||||
case "jp":
|
||||
strings["language"] = "日本語"
|
||||
strings["cafeReset"] = "%d/%dにリセット"
|
||||
strings["ravienteBerserk"] = "<大討伐:猛狂期>が開催されました!"
|
||||
strings["ravienteExtreme"] = "<大討伐:猛狂期【極】>が開催されました!"
|
||||
strings["ravienteExtremeLimited"] = "<大討伐:猛狂期【極】(制限付)>が開催されました!"
|
||||
strings["ravienteBerserkSmall"] = "<大討伐:猛狂期(小数)>が開催されました!"
|
||||
|
||||
strings["guildInviteName"] = "猟団勧誘のご案内"
|
||||
strings["guildInvite"] = "猟団「%s」からの勧誘通知です。\n「勧誘に返答」より、返答を行ってください。"
|
||||
|
||||
strings["guildInviteSuccessName"] = "成功"
|
||||
strings["guildInviteSuccess"] = "あなたは「%s」に参加できました。"
|
||||
|
||||
strings["guildInviteAcceptedName"] = "承諾されました"
|
||||
strings["guildInviteAccepted"] = "招待した狩人が「%s」への招待を承諾しました。"
|
||||
|
||||
strings["guildInviteRejectName"] = "却下しました"
|
||||
strings["guildInviteReject"] = "あなたは「%s」への参加を却下しました。"
|
||||
|
||||
strings["guildInviteDeclinedName"] = "辞退しました"
|
||||
strings["guildInviteDeclined"] = "招待した狩人が「%s」への招待を辞退しました。"
|
||||
default:
|
||||
strings["language"] = "English"
|
||||
strings["cafeReset"] = "Resets on %d/%d"
|
||||
strings["ravienteBerserk"] = "<Great Slaying: Berserk> is being held!"
|
||||
strings["ravienteExtreme"] = "<Great Slaying: Extreme> is being held!"
|
||||
strings["ravienteExtremeLimited"] = "<Great Slaying: Extreme (Limited)> is being held!"
|
||||
strings["ravienteBerserkSmall"] = "<Great Slaying: Berserk (Small)> is being held!"
|
||||
|
||||
strings["guildInviteName"] = "Invitation!"
|
||||
strings["guildInvite"] = "You have been invited to join\n「%s」\nDo you want to accept?"
|
||||
|
||||
strings["guildInviteSuccessName"] = "Success!"
|
||||
strings["guildInviteSuccess"] = "You have successfully joined\n「%s」."
|
||||
|
||||
strings["guildInviteAcceptedName"] = "Accepted"
|
||||
strings["guildInviteAccepted"] = "The recipient accepted your invitation to join\n「%s」."
|
||||
|
||||
strings["guildInviteRejectName"] = "Rejected"
|
||||
strings["guildInviteReject"] = "You rejected the invitation to join\n「%s」."
|
||||
|
||||
strings["guildInviteDeclinedName"] = "Declined"
|
||||
strings["guildInviteDeclined"] = "The recipient declined your invitation to join\n「%s」."
|
||||
}
|
||||
return strings
|
||||
}
|
||||
@@ -116,10 +116,9 @@ func (s *Session) QueueSend(data []byte) {
|
||||
func (s *Session) QueueSendNonBlocking(data []byte) {
|
||||
select {
|
||||
case s.sendPackets <- packet{data, true}:
|
||||
// Enqueued data
|
||||
s.logMessage(binary.BigEndian.Uint16(data[0:2]), data, "Server", s.Name)
|
||||
default:
|
||||
s.logger.Warn("Packet queue too full, dropping!")
|
||||
// Queue too full
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user