mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-12 23:14:36 +01:00
Merge branch 'main' into feature/event-tent
This commit is contained in:
19
AUTHORS.md
19
AUTHORS.md
@@ -1,29 +1,30 @@
|
||||
# List of AUTHORS who contributed over time to the Erupe project
|
||||
# List of authors who contributed to Erupe
|
||||
|
||||
## Point of current development
|
||||
The project is currently developed under https://github.com/ZeruLight/Erupe
|
||||
|
||||
## History of development
|
||||
Development of this project dates back to 2019, and was developed under various umbrellas over time:
|
||||
* Cappuccino (Fist/Ando/Ellie42) (The Erupe Developers), 2019-2020 (https://github.com/Ellie42/Erupe / https://github.com/ricochhet/Erupe-Legacy) (Still active closed source)
|
||||
* Cappuccino (Fist/Ando/Ellie42) ("The Erupe Developers"), 2019-2020 (https://github.com/Ellie42/Erupe / https://github.com/ricochhet/Erupe-Legacy) (Still active closed source)
|
||||
* Einherjar Team, ????-2022 Feb (There is no git history for this period, this team's work was taken and used as a foundation for future repositories)
|
||||
* Community Edition, 2022 (https://github.com/xl3lackout/Erupe)
|
||||
* Zerulight, 2022-2023 (https://github.com/ZeruLight/Erupe)
|
||||
* sekaiwish Fork, 2022 (https://github.com/sekaiwish/Erupe)
|
||||
* ZeruLight, 2022-2023 (https://github.com/ZeruLight/Erupe)
|
||||
|
||||
## Authorship of the code
|
||||
Authorship is assigned for each commit within the git history, which is stored in these git repos:
|
||||
* https://github.com/ZeruLight/Erupe
|
||||
* https://github.com/Ellie42/Erupe
|
||||
* https://github.com/Ellie42/Erupe
|
||||
* https://github.com/ricochhet/Erupe-Legacy
|
||||
* https://github.com/xl3lackout/Erupe
|
||||
|
||||
Note there is a divergence between Ellie42s branch and xl3lackout where history has been lost.
|
||||
|
||||
Unfortunately, we have no detailed information on the history of the Erupe pre-2022
|
||||
if somebody can provide information, please contact us, so that we can make this history available.
|
||||
Note the divergence between Ellie42's branch and xl3lackout's where history has been lost.
|
||||
|
||||
Unfortunately, we have no detailed information on the history of Erupe before 2022.
|
||||
If somebody can provide information, please contact us, so that we can make this history available.
|
||||
|
||||
## Exceptions with third-party libraries
|
||||
The third-party libraries have their own way of addressing authorship and the authorship of commits importing/updating
|
||||
a third-party library reflects who did the importing instead of who wrote the code within the commit.
|
||||
|
||||
The Authors of third-party libraries are not explicitly mentioned, and usually is possible to obtain from the files belonging to the third-party libraries.
|
||||
The authors of third-party libraries are not explicitly mentioned, and usually is possible to obtain from the files belonging to the third-party libraries.
|
||||
12
README.md
12
README.md
@@ -1,6 +1,6 @@
|
||||
# Erupe
|
||||
|
||||
## Client Compatiblity
|
||||
## Client Compatibility
|
||||
### Platforms
|
||||
- PC
|
||||
- PlayStation 3
|
||||
@@ -34,15 +34,15 @@ If you want to modify or compile Erupe yourself, please read on.
|
||||
|
||||
## Docker
|
||||
|
||||
Please see the readme in [docker/README.md](./docker/README.md). At the moment this is only really good for quick installs and checking out development not for production.
|
||||
Please see [docker/README.md](./docker/README.md). This is intended for quick installs and development, not for production.
|
||||
|
||||
## Schemas
|
||||
|
||||
We source control the following schemas:
|
||||
- Initialisation Schemas: These initialise the application database to a clean install from a specific version.
|
||||
- Update Schemas: These are update files they should be ran in order of version to get to the latest schema.
|
||||
- Patch Schemas: These are for development and should be ran from the lastest available update schema or initial schema. These eventually get condensed into `Update Schemas` and then deleted when updated to a new version.
|
||||
- Bundled Schemas: These are demo reference files to allow servers to be able to roll their own shops, distributions gachas and scenarios set ups.
|
||||
- Initialization Schema: This initializes the application database to a specific version (9.1.0).
|
||||
- Update Schemas: These are update files that should be ran on top of the initialization schema.
|
||||
- Patch Schemas: These are for development and should be run after running all initialization and update schema. These get condensed into `Update Schemas` and deleted when updated to a new release.
|
||||
- Bundled Schemas: These are demo reference files to give servers standard set-ups.
|
||||
|
||||
Note: Patch schemas are subject to change! You should only be using them if you are following along with development.
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ func (m *MsgMhfUpdateGuacot) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.EntryCount = bf.ReadUint16()
|
||||
bf.ReadUint16() // Zeroed
|
||||
var temp Goocoo
|
||||
for i := 0; i < int(m.EntryCount); i++ {
|
||||
var temp Goocoo
|
||||
temp.Index = bf.ReadUint32()
|
||||
for j := 0; j < 22; j++ {
|
||||
temp.Data1 = append(temp.Data1, bf.ReadInt16())
|
||||
|
||||
6
schemas/patch-schema/22-clan-changing-room.sql
Normal file
6
schemas/patch-schema/22-clan-changing-room.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE guilds ADD COLUMN IF NOT EXISTS room_rp INT DEFAULT 0;
|
||||
ALTER TABLE guilds ADD COLUMN IF NOT EXISTS room_expiry TIMESTAMP WITHOUT TIME ZONE;
|
||||
|
||||
END;
|
||||
@@ -51,6 +51,8 @@ type Guild struct {
|
||||
MemberCount uint16 `db:"member_count"`
|
||||
RankRP uint32 `db:"rank_rp"`
|
||||
EventRP uint32 `db:"event_rp"`
|
||||
RoomRP uint16 `db:"room_rp"`
|
||||
RoomExpiry time.Time `db:"room_expiry"`
|
||||
Comment string `db:"comment"`
|
||||
PugiName1 string `db:"pugi_name_1"`
|
||||
PugiName2 string `db:"pugi_name_2"`
|
||||
@@ -153,6 +155,8 @@ SELECT
|
||||
g.name,
|
||||
rank_rp,
|
||||
event_rp,
|
||||
room_rp,
|
||||
COALESCE(room_expiry, '1970-01-01') AS room_expiry,
|
||||
main_motto,
|
||||
sub_motto,
|
||||
created_at,
|
||||
@@ -706,7 +710,7 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
bf.WriteUint32(uint32(response))
|
||||
case mhfpacket.OperateGuildDonateRank:
|
||||
bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, false))
|
||||
bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, 0))
|
||||
case mhfpacket.OperateGuildSetApplicationDeny:
|
||||
s.server.db.Exec("UPDATE guilds SET recruiting=false WHERE id=$1", guild.ID)
|
||||
case mhfpacket.OperateGuildSetApplicationAllow:
|
||||
@@ -747,10 +751,11 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
||||
// TODO: This doesn't implement blocking, if someone unlocked the same outfit at the same time
|
||||
s.server.db.Exec(`UPDATE guilds SET pugi_outfits=pugi_outfits+$1 WHERE id=$2`, int(math.Pow(float64(pkt.Data1.ReadUint32()), 2)), guild.ID)
|
||||
case mhfpacket.OperateGuildDonateRoom:
|
||||
// TODO: Where does this go?
|
||||
quantity := uint16(pkt.Data1.ReadUint32())
|
||||
bf.WriteBytes(handleDonateRP(s, quantity, guild, 2))
|
||||
case mhfpacket.OperateGuildDonateEvent:
|
||||
quantity := uint16(pkt.Data1.ReadUint32())
|
||||
bf.WriteBytes(handleDonateRP(s, quantity, guild, true))
|
||||
bf.WriteBytes(handleDonateRP(s, quantity, guild, 1))
|
||||
// TODO: Move this value onto rp_yesterday and reset to 0... daily?
|
||||
s.server.db.Exec(`UPDATE guild_characters SET rp_today=rp_today+$1 WHERE character_id=$2`, quantity, s.charID)
|
||||
case mhfpacket.OperateGuildEventExchange:
|
||||
@@ -794,20 +799,37 @@ func handleChangePugi(s *Session, outfit uint8, guild *Guild, num int) {
|
||||
guild.Save(s)
|
||||
}
|
||||
|
||||
func handleDonateRP(s *Session, amount uint16, guild *Guild, isEvent bool) []byte {
|
||||
func handleDonateRP(s *Session, amount uint16, guild *Guild, _type int) []byte {
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint32(0)
|
||||
saveData, err := GetCharacterSaveData(s, s.charID)
|
||||
if err != nil {
|
||||
return bf.Data()
|
||||
}
|
||||
var resetRoom bool
|
||||
if _type == 2 {
|
||||
var currentRP uint16
|
||||
s.server.db.QueryRow(`SELECT room_rp FROM guilds WHERE id = $1`, guild.ID).Scan(¤tRP)
|
||||
if currentRP+amount >= 30 {
|
||||
amount = 30 - currentRP
|
||||
resetRoom = true
|
||||
}
|
||||
}
|
||||
saveData.RP -= amount
|
||||
saveData.Save(s)
|
||||
updateSQL := "UPDATE guilds SET rank_rp = rank_rp + $1 WHERE id = $2"
|
||||
if isEvent {
|
||||
updateSQL = "UPDATE guilds SET event_rp = event_rp + $1 WHERE id = $2"
|
||||
switch _type {
|
||||
case 0:
|
||||
s.server.db.Exec(`UPDATE guilds SET rank_rp = rank_rp + $1 WHERE id = $2`, amount, guild.ID)
|
||||
case 1:
|
||||
s.server.db.Exec(`UPDATE guilds SET event_rp = event_rp + $1 WHERE id = $2`, amount, guild.ID)
|
||||
case 2:
|
||||
if resetRoom {
|
||||
s.server.db.Exec(`UPDATE guilds SET room_rp = 0 WHERE id = $1`, guild.ID)
|
||||
s.server.db.Exec(`UPDATE guilds SET room_expiry = $1 WHERE id = $2`, TimeAdjusted().Add(time.Hour*24*7), guild.ID)
|
||||
} else {
|
||||
s.server.db.Exec(`UPDATE guilds SET room_rp = room_rp + $1 WHERE id = $2`, amount, guild.ID)
|
||||
}
|
||||
}
|
||||
s.server.db.Exec(updateSQL, amount, guild.ID)
|
||||
bf.Seek(0, 0)
|
||||
bf.WriteUint32(uint32(saveData.RP))
|
||||
return bf.Data()
|
||||
@@ -1001,8 +1023,8 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) {
|
||||
bf.WriteUint8(limit)
|
||||
|
||||
bf.WriteUint32(55000)
|
||||
bf.WriteUint32(0)
|
||||
bf.WriteUint16(0) // Changing Room RP
|
||||
bf.WriteUint32(uint32(guild.RoomExpiry.Unix()))
|
||||
bf.WriteUint16(guild.RoomRP)
|
||||
bf.WriteUint16(0) // Ignored
|
||||
|
||||
if guild.AllianceID > 0 {
|
||||
|
||||
@@ -148,9 +148,21 @@ func removeSessionFromStage(s *Session) {
|
||||
destructEmptySemaphores(s)
|
||||
}
|
||||
|
||||
func isStageFull(s *Session, StageID string) bool {
|
||||
if stage, exists := s.server.stages[StageID]; exists {
|
||||
return len(stage.reservedClientSlots)+len(stage.clients) >= int(stage.maxPlayers)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func handleMsgSysEnterStage(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgSysEnterStage)
|
||||
|
||||
if isStageFull(s, pkt.StageID) {
|
||||
doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x01})
|
||||
return
|
||||
}
|
||||
|
||||
// Push our current stage ID to the movement stack before entering another one.
|
||||
if s.stage != nil {
|
||||
s.stage.Lock()
|
||||
@@ -175,6 +187,12 @@ func handleMsgSysBackStage(s *Session, p mhfpacket.MHFPacket) {
|
||||
backStage = "sl1Ns200p0a0u0"
|
||||
}
|
||||
|
||||
if isStageFull(s, backStage) {
|
||||
s.stageMoveStack.Push(backStage)
|
||||
doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x01})
|
||||
return
|
||||
}
|
||||
|
||||
if _, exists := s.stage.reservedClientSlots[s.charID]; exists {
|
||||
delete(s.stage.reservedClientSlots, s.charID)
|
||||
}
|
||||
@@ -188,6 +206,12 @@ func handleMsgSysBackStage(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
func handleMsgSysMoveStage(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgSysMoveStage)
|
||||
|
||||
if isStageFull(s, pkt.StageID) {
|
||||
doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x01})
|
||||
return
|
||||
}
|
||||
|
||||
doStageTransfer(s, pkt.AckHandle, pkt.StageID)
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ func NewStage(ID string) *Stage {
|
||||
objects: make(map[uint32]*Object),
|
||||
objectIndex: 0,
|
||||
rawBinaryData: make(map[stageBinaryKey][]byte),
|
||||
maxPlayers: 4,
|
||||
maxPlayers: 127,
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -38,25 +38,24 @@ func (s *Session) makeSignResponse(uid uint32) []byte {
|
||||
return bf.Data()
|
||||
}
|
||||
|
||||
bf.WriteUint8(uint8(SIGN_SUCCESS)) // resp_code
|
||||
if (s.server.erupeConfig.PatchServerManifest != "" && s.server.erupeConfig.PatchServerFile != "") || s.client == PS3 {
|
||||
bf.WriteUint8(2)
|
||||
} else {
|
||||
bf.WriteUint8(0)
|
||||
if s.client == PS3 && (s.server.erupeConfig.PatchServerFile == "" || s.server.erupeConfig.PatchServerManifest == "") {
|
||||
bf.WriteUint8(uint8(SIGN_EABORT))
|
||||
return bf.Data()
|
||||
}
|
||||
|
||||
bf.WriteUint8(uint8(SIGN_SUCCESS))
|
||||
bf.WriteUint8(2) // patch server count
|
||||
bf.WriteUint8(1) // entrance server count
|
||||
bf.WriteUint8(uint8(len(chars)))
|
||||
bf.WriteUint32(tokenID)
|
||||
bf.WriteBytes([]byte(sessToken))
|
||||
bf.WriteUint32(uint32(channelserver.TimeAdjusted().Unix()))
|
||||
if s.client == PS3 {
|
||||
ps.Uint8(bf, fmt.Sprintf(`ps3-%s.zerulight.cc`, s.server.erupeConfig.Language), false)
|
||||
ps.Uint8(bf, fmt.Sprintf(`ps3-%s.zerulight.cc`, s.server.erupeConfig.Language), false)
|
||||
ps.Uint8(bf, fmt.Sprintf("%s/ps3", s.server.erupeConfig.PatchServerManifest), false)
|
||||
ps.Uint8(bf, fmt.Sprintf("%s/ps3", s.server.erupeConfig.PatchServerFile), false)
|
||||
} else {
|
||||
if s.server.erupeConfig.PatchServerManifest != "" && s.server.erupeConfig.PatchServerFile != "" {
|
||||
ps.Uint8(bf, s.server.erupeConfig.PatchServerManifest, false)
|
||||
ps.Uint8(bf, s.server.erupeConfig.PatchServerFile, false)
|
||||
}
|
||||
ps.Uint8(bf, s.server.erupeConfig.PatchServerManifest, false)
|
||||
ps.Uint8(bf, s.server.erupeConfig.PatchServerFile, false)
|
||||
}
|
||||
if strings.Split(s.rawConn.RemoteAddr().String(), ":")[0] == "127.0.0.1" {
|
||||
ps.Uint8(bf, fmt.Sprintf("127.0.0.1:%d", s.server.erupeConfig.Entrance.Port), false)
|
||||
|
||||
Reference in New Issue
Block a user