Skip to content

Instantly share code, notes, and snippets.

@Elmuti
Created May 25, 2021 17:36
Show Gist options
  • Save Elmuti/89598a99bea394b7c2f680a1771eb2dd to your computer and use it in GitHub Desktop.
Save Elmuti/89598a99bea394b7c2f680a1771eb2dd to your computer and use it in GitHub Desktop.
local Players = game:GetService("Players")
local ObjectManager = require(game.ReplicatedStorage.ObjectManager)
local DamageInfo = require(game.ReplicatedStorage.Game.DamageInfo)
local HealInfo = require(game.ReplicatedStorage.Game.HealInfo)
local Aura_C = require(game.ReplicatedStorage.Entities.Aura_C)
local Party_C = require(game.ReplicatedStorage.Entities.Party_C)
local CombatText = require(game.ReplicatedStorage.Interface.CombatText)
local ProjectileService = require(game.ReplicatedStorage.Services.ProjectileService_C)
local SpellResult = require(game.ReplicatedStorage.Enums.SpellResult)
local ConsoleService = require(game.ReplicatedStorage.Services.ConsoleService)
local ChatService_C = require(game.ReplicatedStorage.Services.ChatService_C)
local SpellCastResultText = require(game.ReplicatedStorage.Databases.SpellCastResultText)
local MovementFlag = require(game.ReplicatedStorage.Enums.MovementFlag)
local Packet = require(game.ReplicatedStorage.Core.Packet)
local CNetworkService = require(game.ReplicatedStorage.Services.ClientNetworkService)
local Opcodes = require(game.ReplicatedStorage.Enums.Opcodes)
local UnitFactory = require(game.ReplicatedStorage.UnitFactory)
local UnitType = require(game.ReplicatedStorage.Enums.UnitType)
local CPlayerHandlers = {}
function CPlayerHandlers.HandleSetTarget(packet)
local hasTarget = packet:ReadBool()
local unit = ObjectManager.GetObjectByGUID(packet:ReadGUID())
if hasTarget then
local target = ObjectManager.GetObjectByGUID(packet:ReadGUID())
if unit and target then
unit:SetTarget(target)
end
else
unit:SetTarget(nil)
end
end
function CPlayerHandlers.HandleDamageInfo(packet)
local victimGuid = packet:ReadGUID()
local result = packet:ReadUInt8()
local amount = packet:ReadFloat()
local sourceGuid = packet:ReadGUID()
local name = packet:ReadString()
local sourceType = packet:ReadUInt8()
local isCritical = packet:ReadBool()
local school = packet:ReadUInt8()
local victimUnit = ObjectManager.GetObjectByGUID(victimGuid)
local sourceUnit = ObjectManager.GetObjectByGUID(sourceGuid)
local damage = DamageInfo.new({
Victim = victimUnit,
Result = result,
Amount = amount,
Source = sourceUnit,
Name = name,
SourceType = sourceType,
IsCritical = isCritical,
DamageSchool = school,
})
if sourceUnit:IsLocalPlayer() or victimUnit:IsLocalPlayer() then
CombatText.DrawCombatText(damage)
end
if sourceUnit:IsLocalPlayer() then
sourceUnit.DamageDealt:Fire(damage)
CombatText.DrawWorldLabel(damage)
end
end
function CPlayerHandlers.HandleHealInfo(packet)
local victimGuid = packet:ReadGUID()
local result = packet:ReadUInt8()
local amount = packet:ReadFloat()
local sourceGuid = packet:ReadGUID()
local name = packet:ReadString()
local sourceType = packet:ReadUInt8()
local isCritical = packet:ReadBool()
local overheal = packet:ReadFloat()
local victimUnit = ObjectManager.GetObjectByGUID(victimGuid)
local sourceUnit = ObjectManager.GetObjectByGUID(sourceGuid)
local healing = HealInfo.new({
Victim = victimUnit,
Result = result,
Amount = amount,
Source = sourceUnit,
Name = name,
SourceType = sourceType,
IsCritical = isCritical,
Overheal = overheal,
})
if sourceUnit:IsLocalPlayer() or victimUnit:IsLocalPlayer() then
CombatText.DrawCombatText(healing, true)
end
if sourceUnit:IsLocalPlayer() and sourceUnit ~= victimUnit then
--sourceUnit.DamageDealt:Fire(damage)
CombatText.DrawWorldLabel(healing, true)
end
end
-- Server sends initial unit data
function CPlayerHandlers.HandleFullUpdate(packet)
local TEST_SPAWN_POS = Vector3.new(44.503, 42.057, -974.15)
local function GetPlayerByGUID(guid): Player?
for _, player in ipairs(Players:GetPlayers()) do
if player:GetAttribute("GUID") == guid then
return player
end
end
return nil
end
print("Debug: CPlayerHandlers.HandleFullUpdate")
local guid = packet:ReadGUID()
local unitType = packet:ReadUInt8()
-- STUPID HACK
-- delay local unit spawning in development to prevent falling through map
if unitType == UnitType.Player and GetPlayerByGUID(guid) == Players.LocalPlayer then
warn("remove this stupid hack when spawning is fixed!")
wait(5)
if not game:IsLoaded() then
print("game:IsLoaded() false so we're waiting for the workspace to spawn in i guess")
game.Loaded:Wait()
end
-- when the client receives info about its own unit then the loading screen should be hidden
end
local unit = ObjectManager.GetObjectByGUID(guid)
if unit ~= nil then
-- Shouldn't be an error in the future, just reset the unit
error("Server sent initial unit data, client would discard current unit")
end
-- Player_C expects a Player instance
if unitType == UnitType.Player then
unit = UnitFactory.Create({
Player = GetPlayerByGUID(guid),
GUID = guid,
UnitType = unitType,
Template = {
SpawnPosition = TEST_SPAWN_POS,
}
})
else
unit = UnitFactory.Create({
GUID = guid,
UnitType = unitType,
Template = {
SpawnPosition = TEST_SPAWN_POS,
},
})
end
unit:ApplyFullUpdate(packet)
-- Create a dummy unit and add it to object manager
ObjectManager.Add(unit)
if unit:IsLocalPlayer() then
local CharacterController = require(game.ReplicatedStorage.CharacterController)
CharacterController:Enable()
print("LocalPlayer unit setup complete!")
end
end
function CPlayerHandlers.HandleUnitDestroyed(packet)
local guid = packet:ReadGUID()
local unit = ObjectManager.RemoveByGUID(guid)
if not unit then
warn("HandleUnitDestroyed: unit not found in object manager")
return
end
-- todo: make sure units can be destroyed properly
-- unit:Destroy()
end
function CPlayerHandlers.HandleCreateProjectile(packet, model, source, target)
local spin = packet:ReadBool()
ProjectileService.FireProjectile(model, source, target, spin)
end
function CPlayerHandlers.HandleSystemMessage(packet)
warn("got deprecated message HandleSystemMEssage")
local customText = packet:ReadBool()
if customText then
local text = packet:ReadString()
-- TODO: stupid as fuck please fix (UIService? idk)
game.Players.LocalPlayer.PlayerScripts.UIMain.AddSystemMessage:Fire(text)
else
packet:ReadUInt16()
warn("string index not yet implemented for HandleSystemMessage")
end
end
function CPlayerHandlers.HandleCastSpell(packet)
local spellId = packet:ReadString()
local casterGuid = packet:ReadGUID()
local castTime = packet:ReadFloat()
local caster = ObjectManager.GetObjectByGUID(casterGuid)
if caster then
caster:StartCast(spellId, castTime)
-- caster:SetCurrentCastSpellId(spellId)
end
end
function CPlayerHandlers.HandleStoppedCasting(packet)
local casterGuid = packet:ReadGUID()
local caster = ObjectManager.GetObjectByGUID(casterGuid)
if caster then
caster:SetCurrentCastSpellId(nil)
caster:StopCast()
end
end
function CPlayerHandlers.HandleAuraNotify(packet)
local unitGuid = packet:ReadGUID()
local auraGuid = packet:ReadGUID()
local added = packet:ReadBool()
local unit = ObjectManager.GetObjectByGUID(unitGuid)
if not unit then
return false
end
if added then
local auraTemplateId = packet:ReadString()
local duration = packet:ReadFloat()
local casterGuid = packet:ReadGUID()
local caster = ObjectManager.GetObjectByGUID(casterGuid)
local aura = Aura_C:new({
GUID = auraGuid,
AuraId = auraTemplateId,
DurationRemaining = duration,
Caster = caster
})
unit:ApplyAura(aura)
else
unit:RemoveAura(auraGuid)
end
end
function CPlayerHandlers.HandleStatChanged(packet)
local unitGuid = packet:ReadGUID()
local statIndex = packet:ReadUInt8()
local statValue = packet:ReadInt32()
local unit = ObjectManager.GetObjectByGUID(unitGuid)
if unit then
unit:SetStat(statIndex, statValue)
end
end
function CPlayerHandlers.HandleHealthChanged(packet)
local unitGuid = packet:ReadGUID()
local health = packet:ReadInt32()
local unit = ObjectManager.GetObjectByGUID(unitGuid)
if not unit then
return false
end
unit:SetHealth(health)
end
function CPlayerHandlers.HandleMaxHealthChanged(packet)
local unitGuid = packet:ReadGUID()
local maxHealth = packet:ReadInt32()
local unit = ObjectManager.GetObjectByGUID(unitGuid)
if not unit then
return false
end
unit:SetMaxHealth(maxHealth)
end
function CPlayerHandlers.HandleSetRooted(packet)
local rooted = packet:ReadBool()
local unit = ObjectManager.GetLocalUnit()
unit:SetRooted(rooted)
end
function CPlayerHandlers.ChangeCombatState(packet)
local guid = packet:ReadGUID()
local unit = ObjectManager.GetObjectByGUID(guid)
local inCombat = packet:ReadBool()
--unit:SetInCombat
if unit:IsLocalPlayer() then
CombatText.DrawInCombatStatus(inCombat)
end
end
function CPlayerHandlers.HandlePowerChanged(packet)
local guid = packet:ReadGUID()
local unit = ObjectManager.GetObjectByGUID(guid)
if unit then
local power = packet:ReadInt32()
unit:SetPower(power)
end
end
function CPlayerHandlers.HandleMaxPowerChanged(packet)
local guid = packet:ReadGUID()
local unit = ObjectManager.GetObjectByGUID(guid)
if unit then
local power = packet:ReadInt32()
unit:SetMaxPower(power)
end
end
function CPlayerHandlers.HandlePowerTypeChanged(packet)
local guid = packet:ReadGUID()
local unit = ObjectManager.GetObjectByGUID(guid)
if unit then
local powerType = packet:ReadUInt8()
end
end
function CPlayerHandlers.HandlePartyInfo(packet)
local leaderGuid = packet:ReadGUID()
local memberCount = packet:ReadUInt8()
local leader = ObjectManager.GetObjectByGUID(leaderGuid)
if not leader or not leader:IsInParty() then
return false
end
local party = Party_C:new(leader)
for i = 1, memberCount do
local unit = ObjectManager.GetObjectByGUID(packet:ReadGUID())
if not unit then
return false
end
party:AddMember(unit)
end
end
function CPlayerHandlers.HandleUpdateParty(packet)
local leaderGuid = packet:ReadGUID()
local joined = packet:ReadBool()
local leader = ObjectManager.GetObjectByGUID(leaderGuid)
if not leader or not leader:IsInParty() then
return false
end
local party = leader:GetParty()
local unit = ObjectManager.GetObjectByGUID(packet:ReadGUID())
if not unit then
return false
end
if joined then
party:AddMember(unit)
else
party:RemoveMember(unit)
end
end
function CPlayerHandlers.HandleConsoleWriteLine(packet)
local text = packet:ReadString()
local color = packet:ReadColor3()
ConsoleService.WriteLine(text, color)
end
function CPlayerHandlers.HandleChatMessage(packet)
local guid = packet:ReadGUID()
local chatType = packet:ReadUInt8()
local text = packet:ReadString()
local sourceUnit = ObjectManager.GetObjectByGUID(guid)
if not sourceUnit then
warn("Server sent chat from unknown unit")
return false
end
ChatService_C.WriteMessage(sourceUnit, text, chatType)
end
function CPlayerHandlers.HandleSpellCastFailed(packet)
local isCustomText = packet:ReadBool()
local text = nil
if isCustomText then
text = packet:ReadString()
else
local textId = packet:ReadUInt8()
text = SpellCastResultText[textId]
end
if text then
-- TODO: stupid as fuck please fix (UIService? idk)
game.Players.LocalPlayer.PlayerScripts.UIMain.AddSystemMessage:Fire(text)
else
warn("HandleSpellCastFailed received nil text")
end
end
function CPlayerHandlers.HandleSpellCooldown(packet)
local spellId = packet:ReadString()
local cooldownTime = packet:ReadFloat()
local unit = ObjectManager.GetLocalUnit()
if not unit then
warn("No local unit")
return false
end
unit.CooldownChanged:Fire(spellId, cooldownTime)
end
function CPlayerHandlers.HandlePlayerMove(packet)
local guid = packet:ReadGUID()
local movementFlags = packet:ReadUInt8()
local position = packet:ReadVector3()
local angle = packet:ReadAngleCompressed()
local remoteTimestamp = packet:ReadDouble()
local receivedAt = os.clock()
local unit = ObjectManager.GetObjectByGUID(guid)
if not unit then
warn("Server sent movement info for unknown unit")
return false
end
if not unit:IsPlayer() then
warn("Server sent PlayerMove opcode for non-player unit")
return false
end
local x = 0
local z = 0
if bit32.btest(movementFlags, MovementFlag.Forward) then
x = 1
elseif bit32.btest(movementFlags, MovementFlag.Backward) then
x = -1
end
if bit32.btest(movementFlags, MovementFlag.Left) then
z = 1
elseif bit32.btest(movementFlags, MovementFlag.Right) then
z = -1
end
unit:OnMovementInfoReceived(position, Vector3.new(x, 0, z), angle, remoteTimestamp, receivedAt)
end
function CPlayerHandlers.HandleClockSyncRequest(packet)
local token = packet:ReadUInt32()
local now = os.clock()
-- handle response
local packetOut = Packet:new()
packetOut:WriteUInt32(token)
packetOut:WriteDouble(now)
CNetworkService.Send(Opcodes.ClockSync, packetOut)
end
return CPlayerHandlers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment