@@ -3,6 +3,7 @@ package channelserver
import (
"erupe-ce/common/byteframe"
ps "erupe-ce/common/pascalstring"
"erupe-ce/common/stringsupport"
"erupe-ce/common/token"
_config "erupe-ce/config"
"erupe-ce/network/mhfpacket"
@@ -33,62 +34,180 @@ func handleMsgMhfLoadMezfesData(s *Session, p mhfpacket.MHFPacket) {
doAckBufSucceed ( s , pkt . AckHandle , bf . Data ( ) )
}
func generateTournamentTimestamps ( start uint32 , debug bool ) [ ] uint32 {
timestamps := make ( [ ] uint32 , 4 )
midnight := TimeMidnight ( )
if debug && start <= 3 {
midnight := uint32 ( midnight . Unix ( ) )
switch start {
case 1 :
timestamps [ 0 ] = midnight
timestamps [ 1 ] = timestamps [ 0 ] + 259200
timestamps [ 2 ] = timestamps [ 1 ] + 766800
timestamps [ 3 ] = timestamps [ 2 ] + 604800
case 2 :
timestamps [ 0 ] = midnight - 259200
timestamps [ 1 ] = midnight
timestamps [ 2 ] = timestamps [ 1 ] + 766800
timestamps [ 3 ] = timestamps [ 2 ] + 604800
case 3 :
timestamps [ 0 ] = midnight - 1026000
timestamps [ 1 ] = midnight - 766800
timestamps [ 2 ] = midnight
timestamps [ 3 ] = timestamps [ 2 ] + 604800
}
return timestamps
}
timestamps [ 0 ] = start
timestamps [ 1 ] = timestamps [ 0 ] + 259200
timestamps [ 2 ] = timestamps [ 1 ] + 766800
timestamps [ 3 ] = timestamps [ 2 ] + 604800
return timestamps
}
type TournamentEvent struct {
ID uint32
CupGroup uint16
EventSubType int16
QuestFileID uint32
Name string
}
type TournamentCup struct {
ID uint32
CupGroup uint16
Type uint16
Unk uint16
Name string
Description string
}
func handleMsgMhfEnumerateRanking ( s * Session , p mhfpacket . MHFPacket ) {
pkt := p . ( * mhfpacket . MsgMhfEnumerateRanking )
bf := byteframe . NewByteFrame ( )
state := s . server . erupeConfig . DebugOptions . TournamentOverride
// Unk
// Unk
// Start?
// End?
midnight := TimeMidnight ( )
switch state {
case 1 :
bf . WriteUint32 ( uint32 ( midnight . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Add ( 3 * 24 * time . H our) . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Add ( 13 * 24 * time . Hour ) . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Add ( 20 * 24 * time . Hour ) . Unix ( ) ) )
case 2 :
bf . WriteUint32 ( uint32 ( midnight . Add ( - 3 * 24 * time . Hour ) . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Add ( 10 * 24 * time . Hour ) . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Add ( 17 * 24 * time . Hour ) . Unix ( ) ) )
case 3 :
bf . WriteUint32 ( uint32 ( midnight . Add ( - 13 * 24 * time . Hour ) . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Add ( - 10 * 24 * time . H our) . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Unix ( ) ) )
bf . WriteUint32 ( uint32 ( midnight . Add ( 7 * 24 * time . Hour ) . Unix ( ) ) )
default :
id , start := uint32 ( 0xBEEFDEAD ) , uint32 ( 0 )
rows , _ := s . server . db . Queryx ( "SELECT id, (EXTRACT(epoch FROM start_time)::int) as start_time FROM events WHERE event_type='festa'" )
for rows . Next ( ) {
rows . Scan ( & id , & start )
}
var timestamps [ ] uint32
if s . server . erupeConfig . DebugOptions . TournamentOverride >= 0 {
if s . server . erupeConfig . DebugOptions . T ournamentOverride == 0 {
bf . WriteBytes ( make ( [ ] byte , 16 ) )
bf . WriteUint32 ( uint32 ( TimeAdjusted ( ) . Unix ( ) ) )
bf . WriteUint8 ( 0 )
ps . Uint8 ( bf , "" , true )
bf . WriteUint16 ( 0 )
bf . WriteUint8 ( 0 )
doAckBufSucceed ( s , pkt . AckHandle , bf . Data ( ) )
return
}
timestamps = generateTournamentTimestamps ( uint32 ( s . server . erupeConfig . DebugOptions . T ournamentOverride ) , true )
} else {
timestamps = generateTournamentTimestamps ( start , false )
}
if timestamps [ 0 ] > uint32 ( TimeAdjusted ( ) . Unix ( ) ) {
bf . WriteBytes ( make ( [ ] byte , 16 ) )
bf . WriteUint32 ( uint32 ( TimeAdjusted ( ) . Unix ( ) ) ) // TS Current Time
bf . WriteUint8 ( 3 )
bf . WriteBytes ( make ( [ ] byte , 4 ) )
bf . WriteUint32 ( uint32 ( TimeAdjusted ( ) . Unix ( ) ) )
bf . WriteUint8 ( 0 )
ps . Uint8 ( bf , "" , true )
bf . WriteUint16 ( 0 )
bf . WriteUint8 ( 0 )
doAckBufSucceed ( s , pkt . AckHandle , bf . Data ( ) )
return
}
bf . WriteUint32 ( uint32 ( TimeAdjusted ( ) . Unix ( ) ) ) // TS Current Time
bf . WriteUint8 ( 3 )
ps . Uint8 ( bf , "" , false )
bf . WriteUint16 ( 0 ) // numEvents
bf . WriteUint8 ( 0 ) // numCups
/*
struct event
uint32 eventID
uint16 unk
uint16 unk
uint32 unk
psUint8 name
for _ , timestamp := range timestamps {
bf . WriteUint32 ( timestamp )
}
bf . WriteUint32 ( uint32 ( TimeAdjusted ( ) . Unix ( ) ) )
bf . WriteUint8 ( 1 ) // TODO: Make this dynamic depending on timestamp
ps . Uint8 ( bf , "第150回公式狩猟大会" , true )
struct cup
uint32 cupID
uint16 unk
uint16 unk
uint16 unk
psUint8 name
psUint16 desc
*/
// Temp direct port
tournamentEvents := [ ] TournamentEvent {
{ 2644 , 16 , 0 , 60691 , "爆霧竜討伐!" } ,
{ 2645 , 16 , 1 , 60691 , "爆霧竜討伐!" } ,
{ 2646 , 16 , 2 , 60691 , "爆霧竜討伐!" } ,
{ 2647 , 16 , 3 , 60691 , "爆霧竜討伐!" } ,
{ 2648 , 16 , 4 , 60691 , "爆霧竜討伐!" } ,
{ 2649 , 16 , 5 , 60691 , "爆霧竜討伐!" } ,
{ 2650 , 16 , 6 , 60691 , "爆霧竜討伐!" } ,
{ 2651 , 16 , 7 , 60691 , "爆霧竜討伐!" } ,
{ 2652 , 16 , 8 , 60691 , "爆霧竜討伐!" } ,
{ 2653 , 16 , 9 , 60691 , "爆霧竜討伐!" } ,
{ 2654 , 16 , 10 , 60691 , "爆霧竜討伐!" } ,
{ 2655 , 16 , 11 , 60691 , "爆霧竜討伐!" } ,
{ 2656 , 16 , 12 , 60691 , "爆霧竜討伐!" } ,
{ 2657 , 16 , 13 , 60691 , "爆霧竜討伐!" } ,
{ 2658 , 17 , - 1 , 60690 , "みんなで爆霧竜討伐!" } ,
{ 2659 , 6 , 234 , 0 , "キレアジ" } ,
{ 2660 , 6 , 237 , 0 , "ハリマグロ" } ,
{ 2661 , 6 , 239 , 0 , "カクサンデメキン" } ,
}
tournamentCups := [ ] TournamentCup {
{ 569 , 6 , 6 , 0 , "個人 巨大魚杯" , "~C05【競技内容】\n~C00クエストで釣った魚のサイズを競う\n~C04【対象魚】\n~C00キレアジ、\nハリマグロ、カクサンデメキン\n~C07【入賞賞品】\n~C00魚杯のしるし、タルネコ生産券、\nグーク生産券、グーク足生産券、\nグーク解放券(1〜3位)\n/猟団ポイント(1〜100位)\n/匠チケット+ハーフチケット白\n(1〜500位)\n~C03【開催期間】\n~C002019年11月22日 14:00から\n2019年11月25日 14:00まで" } ,
{ 570 , 17 , 7 , 0 , "猟団 G級韋駄天杯" , "~C05【競技内容】\n~C00≪みんなで爆霧竜討伐! ≫を\n同じ猟団に所属する4人までの\n猟団員でいかに早くクリアするか\nを競う\n\n~C07【入賞賞品】\n~C00第147回狩人祭の魂(1〜200位)\n\n~C03【開催期間】\n~C002019年11月22日 14:00から\n2019年11月25日 14:00まで\n\n" } ,
{ 571 , 16 , 7 , 0 , "個人 G級韋駄天杯" , "~C05【競技内容】\n~C00≪爆霧竜討伐! ≫を\nいかに早くクリアするかを競う\n\n~C07【入賞賞品】\n~C00王者のメダル(1位)\n/公式のしるし、タルネコ生産券、\nグーク生産券、グーク足生産券、\nグーク解放券(1〜3位)\n/猟団ポイント(1〜100位)\n/匠チケット+ハーフチケット白\n(1〜500位)\n~C03【開催期間】\n~C002019年11月22日 14:00から\n2019年11月25日 14:00まで" } ,
}
bf . WriteUint16 ( uint16 ( len ( tournamentEvents ) ) )
for _ , event := range tournamentEvents {
bf . WriteUint32 ( event . ID )
bf . WriteUint16 ( event . CupGroup )
bf . WriteInt16 ( event . EventSubType )
bf . WriteUint32 ( event . QuestFileID )
ps . Uint8 ( bf , event . Name , true )
}
bf . WriteUint8 ( uint8 ( len ( tournamentCups ) ) )
for _ , cup := range tournamentCups {
bf . WriteUint32 ( cup . ID )
bf . WriteUint16 ( cup . CupGroup )
bf . WriteUint16 ( cup . Type )
bf . WriteUint16 ( cup . Unk )
ps . Uint8 ( bf , cup . Name , true )
ps . Uint16 ( bf , cup . Description , true )
}
doAckBufSucceed ( s , pkt . AckHandle , bf . Data ( ) )
}
type TournamentRank struct {
CID uint32
Rank uint32
Grade uint16
HR uint16
GR uint16
CharName string
GuildName string
}
func handleMsgMhfEnumerateOrder ( s * Session , p mhfpacket . MHFPacket ) {
pkt := p . ( * mhfpacket . MsgMhfEnumerateOrder )
bf := byteframe . NewByteFrame ( )
bf . WriteUint32 ( pkt . EventID )
bf . WriteUint32 ( uint32 ( TimeAdjusted ( ) . Unix ( ) ) )
tournamentRanks := [ ] TournamentRank { }
bf . WriteUint16 ( uint16 ( len ( tournamentRanks ) ) )
bf . WriteUint16 ( 0 ) // Unk
for _ , rank := range tournamentRanks {
bf . WriteUint32 ( rank . CID )
bf . WriteUint32 ( rank . Rank )
bf . WriteUint16 ( rank . Grade )
bf . WriteUint16 ( 0 )
bf . WriteUint16 ( rank . HR )
if _config . ErupeConfig . RealClientMode >= _config . G10 {
bf . WriteUint16 ( rank . GR )
}
bf . WriteUint16 ( 0 )
bf . WriteUint8 ( uint8 ( len ( rank . CharName ) + 1 ) )
bf . WriteUint8 ( uint8 ( len ( rank . GuildName ) + 1 ) )
bf . WriteNullTerminatedBytes ( stringsupport . UTF8ToSJIS ( rank . CharName ) )
bf . WriteNullTerminatedBytes ( stringsupport . UTF8ToSJIS ( rank . GuildName ) )
}
doAckBufSucceed ( s , pkt . AckHandle , bf . Data ( ) )
}
@@ -127,10 +246,10 @@ func generateFestaTimestamps(s *Session, start uint32, debug bool) []uint32 {
}
return timestamps
}
if start == 0 || TimeAdjusted ( ) . Unix ( ) > int64 ( start ) + 29772 00 {
if start == 0 || TimeAdjusted ( ) . Unix ( ) > int64 ( start ) + 30240 00 {
cleanupFesta ( s )
// Generate a new festa, starting midnight tomorrow
start = uint32 ( midnight . Add ( 24 * time . Hour ) . Unix ( ) )
// Generate a new festa, starting 11am tomorrow
start = uint32 ( midnight . Add ( 35 * time . Hour ) . Unix ( ) )
s . server . db . Exec ( "INSERT INTO events (event_type, start_time) VALUES ('festa', to_timestamp($1)::timestamp without time zone)" , start )
}
timestamps [ 0 ] = start