Closed Rutherther closed 1 year ago
After this is done, the simple apis should be rewritten to use contracts
enum SkillStates {
None,
UseSkillSent,
Casted,
Restored
}
enum SkillErrors {
Unknown,
NoAmmo,
NoMana,
Timeout
}
var skillContract = new ContractBuilder<TStates, TErrors, SkillUsedEvent>(contractor)
.AddMoveGameFilter<SkillUsedEvent>(UseSkillSent, SkillUsed .. for the given vnum, Casted)
.AddEventAction<SkillUsedEvent>(set)
.AddErrorPacketFilter(CancelFilter, MapToSkillErrors)
.AddAction(None, SendPacket(new UseSkill), move to UseSkillSent)
.SetMoveTimeout(Casted, 1000, Restored)
.Build();
var skillUsedEventResult = await skillContract
.Register()
.Execute()
.WaitForAsync(Restored);
if (!skillUsedEventResult.IsDefined(out var skillUsedEvent))
{ // there was an error
return skillUsedEventResult.Error;
}
skillUsedEvent.Target // information about target (hp, id, ...)
Revision v2:
enum SkillStates {
None,
UseSkillSent,
Casted,
Restored
}
enum SkillErrors {
Unknown,
NoAmmo,
NoMana,
Timeout
}
var skillVNum = 123;
var skillContract = new ContractBuilder<SkillStates, SkillErrors, SkillUsedEvent>(contractor, SkillStates.None)
.SetMoveFilter<SkillUsedEvent>(UseSkillSent, e => e.Skill.VNum == skillVNum, Casted)
.SetFillData<SkillUsedEvent>(Casted, e => e)
.SetError<CancelPacket>(c => SkillErrors.Unknown, MapToSkillErrors)
.SetMoveAction(SkillStates.None, () => _client.SendPacket(new UseSkillPacket() { ... }), SkillStates.UseSkillSent)
.SetMoveTimeout(Casted, 1000, Restored) // ?
.Build();
var skillUsedEventResult = await skillContract
.WaitForAsync(Restored);
if (!skillUsedEventResult.IsDefined(out var skillUsedEvent))
{ // there was an error
return skillUsedEventResult.Error;
}
skillUsedEvent.Target // information about target (hp, id, ...)
Sometimes there is a need to wait for a confirmation or cancellation from NosTale server.
Possible use cases:
I will think about how to write this, but the general idea is to make something called "Contract", that contract will have a condition that must be satisfied. It would be great if that condition could be anything. But realistically event fired and packet received will suffice. For these events and packets there will be conditions. It's possible that some contracts will have multiple conditions and in specific order.
The contracts should have a timeout behavior. In case the server is not responding. It would be great if the timeout was changing depending on the current timeout of other things. If the server is not responding to anything, we probably lost the connection. That means there is no point in cancelling the contract. If the connection was restored, the contract could be met. And if the connection is not restored, nothing can be done anyway.
Possibly even things such as walk and attack commands could be rewritten to use contracts instead of current blocking behavior.
The end goal is to have non-blocking methods whose result will be a contract that you may subscribe to.