193 lines
5.5 KiB
C#
193 lines
5.5 KiB
C#
using System;
|
|
using System.Text;
|
|
using Dalamud.Plugin.Services;
|
|
using FFXIVClientStructs.FFXIV.Client.Game.Group;
|
|
using FFXIVClientStructs.FFXIV.Client.System.String;
|
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
|
using FFXIVClientStructs.FFXIV.Client.UI.Info;
|
|
using FFXIVClientStructs.FFXIV.Client.UI.Shell;
|
|
|
|
namespace QuestionableCompanion.Services;
|
|
|
|
public class PartyInviteService
|
|
{
|
|
private readonly IPluginLog log;
|
|
|
|
private readonly IObjectTable objectTable;
|
|
|
|
private readonly IClientState clientState;
|
|
|
|
public PartyInviteService(IPluginLog log, IObjectTable objectTable, IClientState clientState)
|
|
{
|
|
this.log = log;
|
|
this.objectTable = objectTable;
|
|
this.clientState = clientState;
|
|
}
|
|
|
|
public unsafe bool InviteToParty(string characterName, ushort worldId)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(characterName))
|
|
{
|
|
log.Error("[PartyInvite] Character name is null or empty!");
|
|
return false;
|
|
}
|
|
if (worldId == 0)
|
|
{
|
|
log.Error("[PartyInvite] World ID is 0 (invalid)!");
|
|
return false;
|
|
}
|
|
characterName = characterName.Trim();
|
|
try
|
|
{
|
|
InfoModule* infoModule = InfoModule.Instance();
|
|
if (infoModule == null)
|
|
{
|
|
log.Error("[PartyInvite] InfoModule is null!");
|
|
return false;
|
|
}
|
|
InfoProxyPartyInvite* partyInviteProxy = (InfoProxyPartyInvite*)infoModule->GetInfoProxyById(InfoProxyId.PartyInvite);
|
|
if (partyInviteProxy == null)
|
|
{
|
|
log.Error("[PartyInvite] InfoProxyPartyInvite is null!");
|
|
return false;
|
|
}
|
|
ulong contentId = 0uL;
|
|
log.Information($"[PartyInvite] Using name-based invite (ContentId=0, Name={characterName}, World={worldId})");
|
|
log.Information($"[PartyInvite] Sending invite to {characterName}@{worldId} (ContentId: {contentId})");
|
|
fixed (byte* namePtr = Encoding.UTF8.GetBytes(characterName + "\0"))
|
|
{
|
|
bool num = partyInviteProxy->InviteToParty(contentId, namePtr, worldId);
|
|
if (num)
|
|
{
|
|
log.Information($"[PartyInvite] ✓ Successfully sent invite to {characterName}@{worldId}");
|
|
}
|
|
else
|
|
{
|
|
log.Warning($"[PartyInvite] ✗ Failed to send invite to {characterName}@{worldId}");
|
|
}
|
|
return num;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[PartyInvite] Exception: " + ex.Message);
|
|
log.Error("[PartyInvite] StackTrace: " + ex.StackTrace);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public unsafe bool InviteToPartyByContentId(ulong contentId, ushort worldId)
|
|
{
|
|
try
|
|
{
|
|
InfoModule* infoModule = InfoModule.Instance();
|
|
if (infoModule == null)
|
|
{
|
|
log.Error("[PartyInvite] InfoModule is null!");
|
|
return false;
|
|
}
|
|
InfoProxyPartyInvite* partyInviteProxy = (InfoProxyPartyInvite*)infoModule->GetInfoProxyById(InfoProxyId.PartyInvite);
|
|
if (partyInviteProxy == null)
|
|
{
|
|
log.Error("[PartyInvite] InfoProxyPartyInvite is null!");
|
|
return false;
|
|
}
|
|
log.Information($"[PartyInvite] Sending invite to ContentID {contentId}@{worldId}");
|
|
bool num = partyInviteProxy->InviteToPartyContentId(contentId, worldId);
|
|
if (num)
|
|
{
|
|
log.Information($"[PartyInvite] Successfully sent invite to ContentID {contentId}@{worldId}");
|
|
}
|
|
else
|
|
{
|
|
log.Warning($"[PartyInvite] Failed to send invite to ContentID {contentId}@{worldId}");
|
|
}
|
|
return num;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[PartyInvite] Exception: " + ex.Message);
|
|
log.Error("[PartyInvite] StackTrace: " + ex.StackTrace);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public unsafe bool InviteToPartyInInstanceByContentId(ulong contentId)
|
|
{
|
|
try
|
|
{
|
|
InfoModule* infoModule = InfoModule.Instance();
|
|
if (infoModule == null)
|
|
{
|
|
log.Error("[PartyInvite] InfoModule is null!");
|
|
return false;
|
|
}
|
|
InfoProxyPartyInvite* partyInviteProxy = (InfoProxyPartyInvite*)infoModule->GetInfoProxyById(InfoProxyId.PartyInvite);
|
|
if (partyInviteProxy == null)
|
|
{
|
|
log.Error("[PartyInvite] InfoProxyPartyInvite is null!");
|
|
return false;
|
|
}
|
|
log.Information($"[PartyInvite] Sending instance invite to ContentID {contentId}");
|
|
bool num = partyInviteProxy->InviteToPartyInInstanceByContentId(contentId);
|
|
if (num)
|
|
{
|
|
log.Information($"[PartyInvite] Successfully sent instance invite to ContentID {contentId}");
|
|
}
|
|
else
|
|
{
|
|
log.Warning($"[PartyInvite] Failed to send instance invite to ContentID {contentId}");
|
|
}
|
|
return num;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[PartyInvite] Exception: " + ex.Message);
|
|
log.Error("[PartyInvite] StackTrace: " + ex.StackTrace);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public unsafe bool LeaveParty()
|
|
{
|
|
try
|
|
{
|
|
GroupManager* groupManager = GroupManager.Instance();
|
|
if (groupManager == null)
|
|
{
|
|
log.Error("[PartyInvite] GroupManager is null!");
|
|
return false;
|
|
}
|
|
GroupManager.Group* group = groupManager->GetGroup();
|
|
if (group == null || group->MemberCount == 0)
|
|
{
|
|
log.Debug("[PartyInvite] Not in a party");
|
|
return true;
|
|
}
|
|
log.Information($"[PartyInvite] Leaving party (Members: {group->MemberCount})");
|
|
RaptureShellModule* shellModule = RaptureShellModule.Instance();
|
|
if (shellModule == null)
|
|
{
|
|
log.Error("[PartyInvite] RaptureShellModule is null!");
|
|
return false;
|
|
}
|
|
UIModule* uiModule = UIModule.Instance();
|
|
if (uiModule == null)
|
|
{
|
|
log.Error("[PartyInvite] UIModule is null!");
|
|
return false;
|
|
}
|
|
Utf8String* leaveCommand = Utf8String.FromString("/leave");
|
|
shellModule->ExecuteCommandInner(leaveCommand, uiModule);
|
|
leaveCommand->Dtor();
|
|
log.Information("[PartyInvite] Leave command executed successfully");
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[PartyInvite] Exception: " + ex.Message);
|
|
log.Error("[PartyInvite] StackTrace: " + ex.StackTrace);
|
|
return false;
|
|
}
|
|
}
|
|
}
|