mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-28 10:32:55 +01:00
docs: add doc.go files and godoc comments to all packages
Add package-level documentation (doc.go) to all 22 first-party packages and godoc comments to ~150 previously undocumented exported symbols across common/, network/, and server/.
This commit is contained in:
3
server/channelserver/compression/deltacomp/doc.go
Normal file
3
server/channelserver/compression/deltacomp/doc.go
Normal file
@@ -0,0 +1,3 @@
|
||||
// Package deltacomp implements delta-diff decompression for incremental save
|
||||
// data updates sent by the MHF client.
|
||||
package deltacomp
|
||||
4
server/channelserver/compression/nullcomp/doc.go
Normal file
4
server/channelserver/compression/nullcomp/doc.go
Normal file
@@ -0,0 +1,4 @@
|
||||
// Package nullcomp implements null-byte run-length compression used by the MHF
|
||||
// client for save data. The format uses a "cmp 20110113" header and encodes
|
||||
// runs of zero bytes as a (0x00, count) pair.
|
||||
package nullcomp
|
||||
11
server/channelserver/doc.go
Normal file
11
server/channelserver/doc.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// Package channelserver implements the gameplay channel server (TCP port
|
||||
// 54001+) that handles all in-game multiplayer functionality. It manages
|
||||
// player sessions, stage (lobby/quest room) state, guild operations, item
|
||||
// management, event systems, and binary state relay between clients.
|
||||
//
|
||||
// Packet handlers are organized by game system into separate files
|
||||
// (handlers_quest.go, handlers_guild.go, etc.) and registered in
|
||||
// handlers_table.go. Each handler has the signature:
|
||||
//
|
||||
// func(s *Session, p mhfpacket.MHFPacket)
|
||||
package channelserver
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// FestivalColor is a festival color identifier string.
|
||||
type FestivalColor string
|
||||
|
||||
const (
|
||||
@@ -23,12 +24,14 @@ const (
|
||||
FestivalColorRed FestivalColor = "red"
|
||||
)
|
||||
|
||||
// FestivalColorCodes maps festival colors to their numeric codes.
|
||||
var FestivalColorCodes = map[FestivalColor]int16{
|
||||
FestivalColorNone: -1,
|
||||
FestivalColorBlue: 0,
|
||||
FestivalColorRed: 1,
|
||||
}
|
||||
|
||||
// GuildApplicationType is the type of a guild application (applied or invited).
|
||||
type GuildApplicationType string
|
||||
|
||||
const (
|
||||
@@ -36,6 +39,7 @@ const (
|
||||
GuildApplicationTypeInvited GuildApplicationType = "invited"
|
||||
)
|
||||
|
||||
// Guild represents a guild with all its metadata.
|
||||
type Guild struct {
|
||||
ID uint32 `db:"id"`
|
||||
Name string `db:"name"`
|
||||
@@ -64,11 +68,13 @@ type Guild struct {
|
||||
GuildLeader
|
||||
}
|
||||
|
||||
// GuildLeader holds the character ID and name of a guild's leader.
|
||||
type GuildLeader struct {
|
||||
LeaderCharID uint32 `db:"leader_id"`
|
||||
LeaderName string `db:"leader_name"`
|
||||
}
|
||||
|
||||
// GuildIconPart represents one graphical part of a guild icon.
|
||||
type GuildIconPart struct {
|
||||
Index uint16
|
||||
ID uint16
|
||||
@@ -82,6 +88,7 @@ type GuildIconPart struct {
|
||||
PosY uint16
|
||||
}
|
||||
|
||||
// GuildApplication represents a pending guild application or invitation.
|
||||
type GuildApplication struct {
|
||||
ID int `db:"id"`
|
||||
GuildID uint32 `db:"guild_id"`
|
||||
@@ -91,6 +98,7 @@ type GuildApplication struct {
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
}
|
||||
|
||||
// GuildIcon is a composite guild icon made up of multiple parts.
|
||||
type GuildIcon struct {
|
||||
Parts []GuildIconPart
|
||||
}
|
||||
@@ -467,6 +475,7 @@ func (guild *Guild) HasApplicationForCharID(s *Session, charID uint32) (bool, er
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// CreateGuild creates a new guild in the database and adds the session's character as its leader.
|
||||
func CreateGuild(s *Session, guildName string) (int32, error) {
|
||||
transaction, err := s.server.db.Begin()
|
||||
|
||||
@@ -539,6 +548,7 @@ func rollbackTransaction(s *Session, transaction *sql.Tx) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetGuildInfoByID retrieves guild info by guild ID, returning nil if not found.
|
||||
func GetGuildInfoByID(s *Session, guildID uint32) (*Guild, error) {
|
||||
rows, err := s.server.db.Queryx(fmt.Sprintf(`
|
||||
%s
|
||||
@@ -562,6 +572,7 @@ func GetGuildInfoByID(s *Session, guildID uint32) (*Guild, error) {
|
||||
return buildGuildObjectFromDbResult(rows, err, s)
|
||||
}
|
||||
|
||||
// GetGuildInfoByCharacterId retrieves guild info for a character, including applied guilds.
|
||||
func GetGuildInfoByCharacterId(s *Session, charID uint32) (*Guild, error) {
|
||||
rows, err := s.server.db.Queryx(fmt.Sprintf(`
|
||||
%s
|
||||
|
||||
@@ -32,6 +32,7 @@ var achievementCurveMap = map[uint8][]int32{
|
||||
32: achievementCurves[3],
|
||||
}
|
||||
|
||||
// Achievement represents computed achievement data for a character.
|
||||
type Achievement struct {
|
||||
Level uint8
|
||||
Value uint32
|
||||
@@ -42,6 +43,7 @@ type Achievement struct {
|
||||
Trophy uint8
|
||||
}
|
||||
|
||||
// GetAchData computes achievement level and progress from a raw score.
|
||||
func GetAchData(id uint8, score int32) Achievement {
|
||||
curve := achievementCurveMap[id]
|
||||
var ach Achievement
|
||||
|
||||
@@ -109,6 +109,7 @@ func handleMsgMhfGetCafeDuration(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
// CafeBonus represents a cafe duration bonus reward entry.
|
||||
type CafeBonus struct {
|
||||
ID uint32 `db:"id"`
|
||||
TimeReq uint32 `db:"time_req"`
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// CampaignEvent represents a promotional campaign event.
|
||||
type CampaignEvent struct {
|
||||
ID uint32
|
||||
Unk0 uint32
|
||||
@@ -35,6 +36,7 @@ type CampaignEvent struct {
|
||||
Categories []uint16
|
||||
}
|
||||
|
||||
// CampaignCategory represents a category grouping for campaign events.
|
||||
type CampaignCategory struct {
|
||||
ID uint16
|
||||
Type uint8
|
||||
@@ -42,6 +44,7 @@ type CampaignCategory struct {
|
||||
Description string
|
||||
}
|
||||
|
||||
// CampaignLink links a campaign event to its items/rewards.
|
||||
type CampaignLink struct {
|
||||
CategoryID uint16
|
||||
CampaignID uint32
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// RyoudamaReward represents a caravan (Ryoudama) reward entry.
|
||||
type RyoudamaReward struct {
|
||||
Unk0 uint8
|
||||
Unk1 uint8
|
||||
@@ -16,22 +17,26 @@ type RyoudamaReward struct {
|
||||
Unk5 uint16
|
||||
}
|
||||
|
||||
// RyoudamaKeyScore represents a caravan key score entry.
|
||||
type RyoudamaKeyScore struct {
|
||||
Unk0 uint8
|
||||
Unk1 int32
|
||||
}
|
||||
|
||||
// RyoudamaCharInfo represents per-character caravan info.
|
||||
type RyoudamaCharInfo struct {
|
||||
CID uint32
|
||||
Unk0 int32
|
||||
Name string
|
||||
}
|
||||
|
||||
// RyoudamaBoostInfo represents caravan boost status.
|
||||
type RyoudamaBoostInfo struct {
|
||||
Start time.Time
|
||||
End time.Time
|
||||
}
|
||||
|
||||
// Ryoudama represents complete caravan data.
|
||||
type Ryoudama struct {
|
||||
Reward []RyoudamaReward
|
||||
KeyScore []RyoudamaKeyScore
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GetCharacterSaveData loads a character's save data from the database.
|
||||
func GetCharacterSaveData(s *Session, charID uint32) (*CharacterSaveData, error) {
|
||||
result, err := s.server.db.Query("SELECT id, savedata, is_new_character, name FROM characters WHERE id = $1", charID)
|
||||
if err != nil {
|
||||
|
||||
@@ -10,11 +10,13 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// PaperMissionTimetable represents a daily mission schedule entry.
|
||||
type PaperMissionTimetable struct {
|
||||
Start time.Time
|
||||
End time.Time
|
||||
}
|
||||
|
||||
// PaperMissionData represents daily mission details.
|
||||
type PaperMissionData struct {
|
||||
Unk0 uint8
|
||||
Unk1 uint8
|
||||
@@ -25,11 +27,13 @@ type PaperMissionData struct {
|
||||
Reward2Quantity uint8
|
||||
}
|
||||
|
||||
// PaperMission represents a daily mission wrapper.
|
||||
type PaperMission struct {
|
||||
Timetables []PaperMissionTimetable
|
||||
Data []PaperMissionData
|
||||
}
|
||||
|
||||
// PaperData represents complete daily paper data.
|
||||
type PaperData struct {
|
||||
Unk0 uint16
|
||||
Unk1 int16
|
||||
@@ -40,6 +44,7 @@ type PaperData struct {
|
||||
Unk6 int16
|
||||
}
|
||||
|
||||
// PaperGift represents a paper gift reward entry.
|
||||
type PaperGift struct {
|
||||
Unk0 uint16
|
||||
Unk1 uint8
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Distribution represents an item distribution event.
|
||||
type Distribution struct {
|
||||
ID uint32 `db:"id"`
|
||||
Deadline time.Time `db:"deadline"`
|
||||
@@ -119,6 +120,7 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
// DistributionItem represents a single item in a distribution.
|
||||
type DistributionItem struct {
|
||||
ItemType uint8 `db:"item_type"`
|
||||
ID uint32 `db:"id"`
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Event represents an in-game event entry.
|
||||
type Event struct {
|
||||
EventType uint16
|
||||
Unk1 uint16
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Gacha represents a gacha lottery definition.
|
||||
type Gacha struct {
|
||||
ID uint32 `db:"id"`
|
||||
MinGR uint32 `db:"min_gr"`
|
||||
@@ -22,6 +23,7 @@ type Gacha struct {
|
||||
Hidden bool `db:"hidden"`
|
||||
}
|
||||
|
||||
// GachaEntry represents a gacha entry (step/box).
|
||||
type GachaEntry struct {
|
||||
EntryType uint8 `db:"entry_type"`
|
||||
ID uint32 `db:"id"`
|
||||
@@ -36,6 +38,7 @@ type GachaEntry struct {
|
||||
Name string `db:"name"`
|
||||
}
|
||||
|
||||
// GachaItem represents a single item in a gacha pool.
|
||||
type GachaItem struct {
|
||||
ItemType uint8 `db:"item_type"`
|
||||
ItemID uint16 `db:"item_id"`
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GuildAdventure represents a guild adventure expedition.
|
||||
type GuildAdventure struct {
|
||||
ID uint32 `db:"id"`
|
||||
Destination uint32 `db:"destination"`
|
||||
|
||||
@@ -28,6 +28,7 @@ END
|
||||
FROM guild_alliances ga
|
||||
`
|
||||
|
||||
// GuildAlliance represents a multi-guild alliance.
|
||||
type GuildAlliance struct {
|
||||
ID uint32 `db:"id"`
|
||||
Name string `db:"name"`
|
||||
@@ -43,6 +44,7 @@ type GuildAlliance struct {
|
||||
SubGuild2 Guild
|
||||
}
|
||||
|
||||
// GetAllianceData loads alliance data from the database.
|
||||
func GetAllianceData(s *Session, AllianceID uint32) (*GuildAlliance, error) {
|
||||
rows, err := s.server.db.Queryx(fmt.Sprintf(`
|
||||
%s
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// MessageBoardPost represents a guild message board post.
|
||||
type MessageBoardPost struct {
|
||||
ID uint32 `db:"id"`
|
||||
StampID uint32 `db:"stamp_id"`
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GuildMeal represents a guild cooking meal entry.
|
||||
type GuildMeal struct {
|
||||
ID uint32 `db:"id"`
|
||||
MealID uint32 `db:"meal_id"`
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GuildMember represents a guild member with role and stats.
|
||||
type GuildMember struct {
|
||||
GuildID uint32 `db:"guild_id"`
|
||||
CharID uint32 `db:"character_id"`
|
||||
@@ -92,6 +93,7 @@ SELECT
|
||||
LEFT JOIN guilds g ON g.id = gc.guild_id
|
||||
`
|
||||
|
||||
// GetGuildMembers loads all members of a guild.
|
||||
func GetGuildMembers(s *Session, guildID uint32, applicants bool) ([]*GuildMember, error) {
|
||||
rows, err := s.server.db.Queryx(fmt.Sprintf(`
|
||||
%s
|
||||
@@ -120,6 +122,7 @@ func GetGuildMembers(s *Session, guildID uint32, applicants bool) ([]*GuildMembe
|
||||
return members, nil
|
||||
}
|
||||
|
||||
// GetCharacterGuildData loads a character's guild membership.
|
||||
func GetCharacterGuildData(s *Session, charID uint32) (*GuildMember, error) {
|
||||
rows, err := s.server.db.Queryx(fmt.Sprintf("%s WHERE character.character_id=$1", guildMembersSelectSQL), charID)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"erupe-ce/network/mhfpacket"
|
||||
)
|
||||
|
||||
// GuildMission represents a guild mission entry.
|
||||
type GuildMission struct {
|
||||
ID uint32
|
||||
Unk uint32
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// TreasureHunt represents a guild treasure hunt entry.
|
||||
type TreasureHunt struct {
|
||||
HuntID uint32 `db:"id"`
|
||||
HostID uint32 `db:"host_id"`
|
||||
@@ -147,6 +148,7 @@ func handleMsgMhfOperateGuildTresureReport(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
|
||||
// TreasureSouvenir represents a guild treasure souvenir entry.
|
||||
type TreasureSouvenir struct {
|
||||
Destination uint32
|
||||
Quantity uint32
|
||||
|
||||
@@ -47,6 +47,7 @@ func handleMsgMhfUpdateInterior(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
|
||||
// HouseData represents player house/my house data.
|
||||
type HouseData struct {
|
||||
CharID uint32 `db:"id"`
|
||||
HR uint16 `db:"hr"`
|
||||
@@ -329,6 +330,7 @@ func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
|
||||
// Title represents a hunter title entry.
|
||||
type Title struct {
|
||||
ID uint16 `db:"id"`
|
||||
Acquired time.Time `db:"unlocked_at"`
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Mail represents an in-game mail message.
|
||||
type Mail struct {
|
||||
ID int `db:"id"`
|
||||
SenderID uint32 `db:"sender_id"`
|
||||
@@ -79,6 +80,7 @@ func (m *Mail) MarkRead(s *Session) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMailListForCharacter loads all mail for a character.
|
||||
func GetMailListForCharacter(s *Session, charID uint32) ([]Mail, error) {
|
||||
rows, err := s.server.db.Queryx(`
|
||||
SELECT
|
||||
@@ -127,6 +129,7 @@ func GetMailListForCharacter(s *Session, charID uint32) ([]Mail, error) {
|
||||
return allMail, nil
|
||||
}
|
||||
|
||||
// GetMailByID loads a single mail by ID.
|
||||
func GetMailByID(s *Session, ID int) (*Mail, error) {
|
||||
row := s.server.db.QueryRowx(`
|
||||
SELECT
|
||||
@@ -167,6 +170,7 @@ func GetMailByID(s *Session, ID int) (*Mail, error) {
|
||||
return mail, nil
|
||||
}
|
||||
|
||||
// SendMailNotification sends a new mail notification to a player.
|
||||
func SendMailNotification(s *Session, m *Mail, recipient *Session) {
|
||||
bf := byteframe.NewByteFrame()
|
||||
|
||||
|
||||
@@ -370,6 +370,7 @@ func handleMsgMhfEnumerateAiroulist(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
}
|
||||
|
||||
// Airou represents Airou (felyne companion) data.
|
||||
type Airou struct {
|
||||
ID uint32
|
||||
Name []byte
|
||||
@@ -445,6 +446,7 @@ func getGuildAirouList(s *Session) []Airou {
|
||||
return guildCats
|
||||
}
|
||||
|
||||
// GetAirouDetails parses Airou data from a ByteFrame.
|
||||
func GetAirouDetails(bf *byteframe.ByteFrame) []Airou {
|
||||
catCount := bf.ReadUint8()
|
||||
cats := make([]Airou, catCount)
|
||||
|
||||
@@ -241,6 +241,7 @@ func handleMsgMhfGetLobbyCrowd(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 0x320))
|
||||
}
|
||||
|
||||
// TrendWeapon represents trending weapon usage data.
|
||||
type TrendWeapon struct {
|
||||
WeaponType uint8
|
||||
WeaponID uint16
|
||||
|
||||
@@ -48,6 +48,7 @@ func equal(a, b []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// BackportQuest converts a quest binary to an older format.
|
||||
func BackportQuest(data []byte) []byte {
|
||||
wp := binary.LittleEndian.Uint32(data[0:4]) + 96
|
||||
rp := wp + 4
|
||||
|
||||
@@ -48,6 +48,7 @@ func handleMsgMhfReleaseEvent(s *Session, p mhfpacket.MHFPacket) {
|
||||
})
|
||||
}
|
||||
|
||||
// RaviUpdate represents a Raviente register update entry.
|
||||
type RaviUpdate struct {
|
||||
Op uint8
|
||||
Dest uint8
|
||||
|
||||
@@ -107,6 +107,7 @@ const rengokuScoreQuery = `, c.name FROM rengoku_score rs
|
||||
LEFT JOIN characters c ON c.id = rs.character_id
|
||||
LEFT JOIN guild_characters gc ON gc.character_id = rs.character_id `
|
||||
|
||||
// RengokuScore represents a Rengoku (Hunting Road) ranking score.
|
||||
type RengokuScore struct {
|
||||
Name string `db:"name"`
|
||||
Score uint32 `db:"score"`
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Scenario represents scenario counter data.
|
||||
type Scenario struct {
|
||||
MainID uint32
|
||||
// 0 = Basic
|
||||
|
||||
@@ -6,27 +6,32 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// SeibattleTimetable represents a seibattle schedule entry.
|
||||
type SeibattleTimetable struct {
|
||||
Start time.Time
|
||||
End time.Time
|
||||
}
|
||||
|
||||
// SeibattleKeyScore represents a seibattle key score.
|
||||
type SeibattleKeyScore struct {
|
||||
Unk0 uint8
|
||||
Unk1 int32
|
||||
}
|
||||
|
||||
// SeibattleCareer represents seibattle career stats.
|
||||
type SeibattleCareer struct {
|
||||
Unk0 uint16
|
||||
Unk1 uint16
|
||||
Unk2 uint16
|
||||
}
|
||||
|
||||
// SeibattleOpponent represents seibattle opponent data.
|
||||
type SeibattleOpponent struct {
|
||||
Unk0 int32
|
||||
Unk1 int8
|
||||
}
|
||||
|
||||
// SeibattleConventionResult represents a seibattle convention result.
|
||||
type SeibattleConventionResult struct {
|
||||
Unk0 uint32
|
||||
Unk1 uint16
|
||||
@@ -35,10 +40,12 @@ type SeibattleConventionResult struct {
|
||||
Unk4 uint16
|
||||
}
|
||||
|
||||
// SeibattleCharScore represents a seibattle per-character score.
|
||||
type SeibattleCharScore struct {
|
||||
Unk0 uint32
|
||||
}
|
||||
|
||||
// SeibattleCurResult represents a seibattle current result.
|
||||
type SeibattleCurResult struct {
|
||||
Unk0 uint32
|
||||
Unk1 uint16
|
||||
@@ -46,6 +53,7 @@ type SeibattleCurResult struct {
|
||||
Unk3 uint16
|
||||
}
|
||||
|
||||
// Seibattle represents complete seibattle data.
|
||||
type Seibattle struct {
|
||||
Timetable []SeibattleTimetable
|
||||
KeyScore []SeibattleKeyScore
|
||||
@@ -159,6 +167,7 @@ func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
// WeeklySeibatuRankingReward represents a weekly seibattle ranking reward.
|
||||
type WeeklySeibatuRankingReward struct {
|
||||
Unk0 int32
|
||||
Unk1 int32
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// ShopItem represents a shop item listing.
|
||||
type ShopItem struct {
|
||||
ID uint32 `db:"id"`
|
||||
ItemID uint32 `db:"item_id"`
|
||||
@@ -248,6 +249,7 @@ func handleMsgMhfAcquireExchangeShop(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
}
|
||||
|
||||
// FPointExchange represents a frontier point exchange entry.
|
||||
type FPointExchange struct {
|
||||
ID uint32 `db:"id"`
|
||||
ItemType uint8 `db:"item_type"`
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// TournamentInfo0 represents tournament information (type 0).
|
||||
type TournamentInfo0 struct {
|
||||
ID uint32
|
||||
MaxPlayers uint32
|
||||
@@ -28,6 +29,7 @@ type TournamentInfo0 struct {
|
||||
Unk6 string
|
||||
}
|
||||
|
||||
// TournamentInfo21 represents tournament information (type 21).
|
||||
type TournamentInfo21 struct {
|
||||
Unk0 uint32
|
||||
Unk1 uint32
|
||||
@@ -35,6 +37,7 @@ type TournamentInfo21 struct {
|
||||
Unk3 uint8
|
||||
}
|
||||
|
||||
// TournamentInfo22 represents tournament information (type 22).
|
||||
type TournamentInfo22 struct {
|
||||
Unk0 uint32
|
||||
Unk1 uint32
|
||||
@@ -110,6 +113,7 @@ func handleMsgMhfEntryTournament(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
|
||||
// TournamentReward represents a tournament reward entry.
|
||||
type TournamentReward struct {
|
||||
Unk0 uint16
|
||||
Unk1 uint16
|
||||
|
||||
@@ -14,21 +14,25 @@ import (
|
||||
"erupe-ce/network/mhfpacket"
|
||||
)
|
||||
|
||||
// TowerInfoTRP represents tower RP (points) info.
|
||||
type TowerInfoTRP struct {
|
||||
TR int32
|
||||
TRP int32
|
||||
}
|
||||
|
||||
// TowerInfoSkill represents tower skill info.
|
||||
type TowerInfoSkill struct {
|
||||
TSP int32
|
||||
Skills []int16 // 64
|
||||
}
|
||||
|
||||
// TowerInfoHistory represents tower clear history.
|
||||
type TowerInfoHistory struct {
|
||||
Unk0 []int16 // 5
|
||||
Unk1 []int16 // 5
|
||||
}
|
||||
|
||||
// TowerInfoLevel represents tower level info.
|
||||
type TowerInfoLevel struct {
|
||||
Floors int32
|
||||
Unk1 int32
|
||||
@@ -36,6 +40,7 @@ type TowerInfoLevel struct {
|
||||
Unk3 int32
|
||||
}
|
||||
|
||||
// EmptyTowerCSV creates an empty CSV string of the given length.
|
||||
func EmptyTowerCSV(len int) string {
|
||||
temp := make([]string, len)
|
||||
for i := range temp {
|
||||
@@ -194,6 +199,7 @@ var tenrouiraiData = []TenrouiraiData{
|
||||
{2, 6, 40, 0, 3, 1, 0, 0, 1, 1},
|
||||
}
|
||||
|
||||
// TenrouiraiProgress represents Tenrouirai (sky corridor) progress.
|
||||
type TenrouiraiProgress struct {
|
||||
Page uint8
|
||||
Mission1 uint16
|
||||
@@ -201,17 +207,20 @@ type TenrouiraiProgress struct {
|
||||
Mission3 uint16
|
||||
}
|
||||
|
||||
// TenrouiraiReward represents a Tenrouirai reward.
|
||||
type TenrouiraiReward struct {
|
||||
Index uint8
|
||||
Item []uint16 // 5
|
||||
Quantity []uint8 // 5
|
||||
}
|
||||
|
||||
// TenrouiraiKeyScore represents a Tenrouirai key score.
|
||||
type TenrouiraiKeyScore struct {
|
||||
Unk0 uint8
|
||||
Unk1 int32
|
||||
}
|
||||
|
||||
// TenrouiraiData represents Tenrouirai data.
|
||||
type TenrouiraiData struct {
|
||||
Block uint8
|
||||
Mission uint8
|
||||
@@ -231,17 +240,20 @@ type TenrouiraiData struct {
|
||||
Skill6 uint8 // 50
|
||||
}
|
||||
|
||||
// TenrouiraiCharScore represents a Tenrouirai per-character score.
|
||||
type TenrouiraiCharScore struct {
|
||||
Score int32
|
||||
Name string
|
||||
}
|
||||
|
||||
// TenrouiraiTicket represents a Tenrouirai ticket entry.
|
||||
type TenrouiraiTicket struct {
|
||||
Unk0 uint8
|
||||
RP uint32
|
||||
Unk2 uint32
|
||||
}
|
||||
|
||||
// Tenrouirai represents complete Tenrouirai data.
|
||||
type Tenrouirai struct {
|
||||
Progress []TenrouiraiProgress
|
||||
Reward []TenrouiraiReward
|
||||
@@ -429,11 +441,13 @@ func handleMsgMhfPresentBox(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||
}
|
||||
|
||||
// GemInfo represents gem (decoration) info.
|
||||
type GemInfo struct {
|
||||
Gem uint16
|
||||
Quantity uint16
|
||||
}
|
||||
|
||||
// GemHistory represents gem usage history.
|
||||
type GemHistory struct {
|
||||
Gem uint16
|
||||
Message uint16
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"erupe-ce/server/channelserver/compression/nullcomp"
|
||||
)
|
||||
|
||||
// SavePointer identifies a section within the character save data blob.
|
||||
type SavePointer int
|
||||
|
||||
const (
|
||||
@@ -29,6 +30,7 @@ const (
|
||||
lBookshelfData
|
||||
)
|
||||
|
||||
// CharacterSaveData holds a character's save data and its parsed fields.
|
||||
type CharacterSaveData struct {
|
||||
CharID uint32
|
||||
Name string
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Raviente holds shared state for the Raviente siege event.
|
||||
type Raviente struct {
|
||||
sync.Mutex
|
||||
id uint16
|
||||
|
||||
@@ -264,6 +264,7 @@ func (s *Server) BroadcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session)
|
||||
}
|
||||
}
|
||||
|
||||
// WorldcastMHF broadcasts a packet to all sessions across all channel servers.
|
||||
func (s *Server) WorldcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session, ignoredChannel *Server) {
|
||||
for _, c := range s.Channels {
|
||||
if c == ignoredChannel {
|
||||
@@ -292,6 +293,7 @@ func (s *Server) BroadcastChatMessage(message string) {
|
||||
}, nil)
|
||||
}
|
||||
|
||||
// DiscordChannelSend sends a chat message to the configured Discord channel.
|
||||
func (s *Server) DiscordChannelSend(charName string, content string) {
|
||||
if s.erupeConfig.Discord.Enabled && s.discordBot != nil {
|
||||
message := fmt.Sprintf("**%s**: %s", charName, content)
|
||||
@@ -299,6 +301,7 @@ func (s *Server) DiscordChannelSend(charName string, content string) {
|
||||
}
|
||||
}
|
||||
|
||||
// DiscordScreenShotSend sends a screenshot link to the configured Discord channel.
|
||||
func (s *Server) DiscordScreenShotSend(charName string, title string, description string, articleToken string) {
|
||||
if s.erupeConfig.Discord.Enabled && s.discordBot != nil {
|
||||
imageUrl := fmt.Sprintf("%s:%d/api/ss/bbs/%s", s.erupeConfig.Screenshots.Host, s.erupeConfig.Screenshots.Port, articleToken)
|
||||
@@ -307,6 +310,7 @@ func (s *Server) DiscordScreenShotSend(charName string, title string, descriptio
|
||||
}
|
||||
}
|
||||
|
||||
// FindSessionByCharID looks up a session by character ID across all channels.
|
||||
func (s *Server) FindSessionByCharID(charID uint32) *Session {
|
||||
for _, c := range s.Channels {
|
||||
for _, session := range c.sessions {
|
||||
@@ -318,6 +322,7 @@ func (s *Server) FindSessionByCharID(charID uint32) *Session {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DisconnectUser disconnects all sessions belonging to the given user ID.
|
||||
func (s *Server) DisconnectUser(uid uint32) {
|
||||
var cid uint32
|
||||
var cids []uint32
|
||||
@@ -343,6 +348,7 @@ func (s *Server) DisconnectUser(uid uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
// FindObjectByChar finds a stage object owned by the given character ID.
|
||||
func (s *Server) FindObjectByChar(charID uint32) *Object {
|
||||
s.stagesLock.RLock()
|
||||
defer s.stagesLock.RUnlock()
|
||||
@@ -361,6 +367,7 @@ func (s *Server) FindObjectByChar(charID uint32) *Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasSemaphore checks if the given session is hosting any semaphore.
|
||||
func (s *Server) HasSemaphore(ses *Session) bool {
|
||||
for _, semaphore := range s.semaphore {
|
||||
if semaphore.host == ses {
|
||||
@@ -370,6 +377,7 @@ func (s *Server) HasSemaphore(ses *Session) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Season returns the current in-game season (0-2) based on server ID and time.
|
||||
func (s *Server) Season() uint8 {
|
||||
sid := int64(((s.ID & 0xFF00) - 4096) / 256)
|
||||
return uint8(((TimeAdjusted().Unix() / 86400) + sid) % 3)
|
||||
|
||||
@@ -323,6 +323,7 @@ func (s *Session) getObjectId() uint32 {
|
||||
return uint32(s.objectID)<<16 | uint32(s.objectIndex)
|
||||
}
|
||||
|
||||
// GetSemaphoreID returns the semaphore ID held by the session, varying by semaphore mode.
|
||||
func (s *Session) GetSemaphoreID() uint32 {
|
||||
if s.semaphoreMode {
|
||||
return 0x000E0000 + uint32(s.semaphoreID[1])
|
||||
|
||||
@@ -5,6 +5,11 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// TimeAdjusted, TimeMidnight, TimeWeekStart, TimeWeekNext, and TimeGameAbsolute
|
||||
// are package-level wrappers around the gametime utility functions, providing
|
||||
// convenient access to adjusted server time, daily/weekly boundaries, and the
|
||||
// absolute game timestamp used by the MHF client.
|
||||
|
||||
func TimeAdjusted() time.Time { return gametime.Adjusted() }
|
||||
func TimeMidnight() time.Time { return gametime.Midnight() }
|
||||
func TimeWeekStart() time.Time { return gametime.WeekStart() }
|
||||
|
||||
Reference in New Issue
Block a user