Difference between revisions of "Old Wiki:Contract System"
Jump to navigation
Jump to search
(Bot: Automated import of articles) |
(No difference)
|
Latest revision as of 15:19, 3 April 2021
This is just a copy of my local contract system documentation:
/**********************
* contractMgrService *
**********************/
ContractMgrService::Handle_NumRequeringAttention
Should return a PyDict with 2 values
|-> n = Number of contracts that requires attention and are not from corp
\-> ncorp = Number of contracts that requires attention and are from corp
It's called at the "entering the station sequence" and makes the contract icons to blink
ContractMgrService::Handle_CollectMyPageInfo
Should return a PyDict with this data:
|->numOutstandingContractsNonCorp = ChrContractInfo.numOutstandingContractsNonCorp
|->numOutstandingContractsForCorp = ChrContractInfo.numOutstandingContractsForCorp
|->numOutstandingContracts = ChrContractInfo.numOutstandingContracts
|->numOutstandingContractsLeft = ChrContractInfo.numOutstandingContractsLeft
|->numRequiresAttention = ChrContractInfo.numRequiresAttention
|->numRequiresAttentionCorp = ChrContractInfo.numRequiresAttention
|->numAssignedTo = ChrContractInfo.numAssignedTo
|->numAssignedToCorp = ChrContractInfo.numAssignedToCorp
|->numBiddingOn = ChrContractInfo.numBiddingOn
|->numInProgress = ChrContractInfo.numInProgress
|->numBiddingOnCorp = ChrContractInfo.numBiddingOnCorp
\->numInProgressCorp = ChrContractInfo.numInProgressCorp
ContractMgrService::Handle_NumOutstandingContracts
Should return ChrContractInfo.numOutstandingContracts
ContractMgrService::Handle_GetItemsInStation
Im not completely sure as i havent time to do some test with this but maybe the client sends a INT with the station where look at
return all the items in the station, if not arg is given return the items in the actual station
ContractMgrService::Handle_CreateContract
Should return a PyInt with the id of the contract
It's called when Finish button of Create Contract form is pressed
The client sends those args:
<elementDef name="Call_CreateContract">
<tupleInline>
<int name="type" default="0" none_marker="0" />
<int name="avail" default="0" none_marker="0" />
<int name="assigneeID" default="0" none_marker="0" />
<int name="expiretime" default="0" none_marker="0" />
<int name="duration" default="0" none_marker="0" />
<int name="startStationID" default="0" none_marker="0" />
<int name="endStationID" default="0" none_marker="0" />
<long name="price" default="0" none_marker="0" />
<long name="collateral" default="0" none_marker="0" />
<long name="reward" default="0" none_marker="0" />
<wstring name="title" none_marker="0" />
<string name="description" none_marker="0"/>
</tupleInline>
</elementDef>
Also the client sends a sub-call part with some useful PyDicts and ints:
|->requestItemTypeList = PyDict, contains typeID and quantity of items requested
|->flag = INT, contains the flag of the items selected, maybe it can be a dict too ?
|->itemList = PyDict, contains itemID and quantity of items that the user will give, those need to be moved from the user's hangars
\->forCorp = BOOL, indicates if the contract is for corp or for character
Steps for create a contract:
Step 1: Check if the client has contracts left from ChrContractInfo, if not return false
Step 2: Create a "crate"( cargo container or something like ? ) with location in the current station and ownerID = 1
Step 3: Read one by one the ids of the itemList and do this with each one
Step 3.1: Get the volume of the item and add it to general volume of the contract
Step 3.2: Change the location of the item to the crate created recently
Step 3.3: Add the basic item data to ContractItems with get = false, inCrate = crateID created in Step 1
Step 4: Read one by one the ids of the requestItemTypeList and do this with each one
Setp 4.1: Add the basic item data to ContractItems with get = true and itemID = false
Step 5: Add the contract information to ContractInfo
Step 6: Update the ChrContractInfo table, so reflects one more contract
Step 7: Return the contractID of the contract to the client
ContractMgrService::Handle_GetContract
The client will send a single Integer Arg
Should return a dict with these values:
|->contract = ContractInfo WHERE contractID = arg
|->items = ContractItems WHERE contractID = arg
\->bids = ContractBids WHERE contractID = arg
ContractMgrService::Handle_DeleteContract
The client will send these args:
<elementDef name="Call_DeleteContract">
<tupleInline>
<int name="contractID" /> <!-- Never should be null/none-->
<objectInline>
<!-- Not sure for what we need this info -->
<stringInline value="util.KeyVal" />
<tupleInline>
<int name="type" default="0" none_marker="0" />
<int name="avail" default="0" none_marker="0" />
<int name="assigneeID" default="0" none_marker="0" />
<int name="expiretime" default="0" none_marker="0" />
<int name="duration" default="0" none_marker="0" />
<int name="startStationID" default="0" none_marker="0" />
<int name="endStationID" default="0" none_marker="0" />
<long name="price" default="0" none_marker="0" />
<long name="collateral" default="0" none_marker="0" />
<long name="reward" default="0" none_marker="0" />
<wstring name="title" />
<string name="description" />
</tupleInline>
</objectInline>
</tupleInline>
</elementDef>
Should return true or false if the contract was/wasn't deleted
First it should check that the contract information in the DB is equal to the contract information sent by client
If is equal
Get the crate ID and delete it without deleting the items
Get all the items from ContractItems WHERE contractID = contractID sent by the client AND get = false
Change the location of the item to ContractInfo.locationID so the items come back to your hangar
Delete all the items from ContractItems WHERE contractID = contractID sent by the client
Update the ChrContractInfo data for issuerID of the contract depending on forCorp value and more:
// These queryes can't fail if the DB is correctly installed so we don't need to check them
if( ( requiresAttention ) && ( !forCorp ) )sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET requiresAttention=requiresAttention-1 WHERE characterID=%d", contractOwnerID);
if( ( requiresAttention ) && ( forCorp ) )sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET requiresAttentionCorp=requiresAttentionCorp-1 WHERE characterID=%d", contractOwnerID);
if( ( isAccepted ) && ( !forCorp ) )sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numInProgress=numInProgress-1 WHERE characterID=%d", acceptorID);
if( ( isAccepted ) && ( forCorp ) )sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numInProgressCorp=numInProgressCorp-1 WHERE characterID=%d", acceptorID);
if( !forCorp )sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numOutstandingContractsNonCorp=numOutstandingContractsNonCorp-1 WHERE characterID=%d", contractOwnerID);
if( forCorp )sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numOutstandingContractsForCorp=numOutstandingContractsForCorp-1 WHERE characterID=%d", contractOwnerID);
sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numOutstandingContracts=numOutstandingContracts-1 WHERE characterID=%d", contractOwnerID);
Delete the contract info and return true to the client
If is not equal
SendNotifyMessage like: "The contract has changed, please review these changes first"
Return false to the client
ContractMgrService::Handle_GetContractListForOwner
The client will send these args:
<elementDef name="Call_GetContractListForOwner">
<tupleInline>
<int name="characterID" />
<int name="status" none_marker="0" />
<int name="contractType" none_marker="0" />
<bool name="isAccepted" none_marker="false" />
</tupleInline>
</elementDef>
First it should check for ContractInfo WHERE issuerID = characterID AND status = status AND type = contractType AND isAccepted = isAccepted and fetch it from the DB
Now should read all the contractIDs from the last query and fetch ContractItems WHERE contractID = ContractInfo.contractID
Should return a dict with these values:
|->contract = First query
\->items = Second query
ContractMgrService::Handle_GetContractList
The client will send these args:
<elementDef name="Call_GetContractList" >
<tupleInline>
<int name="type" />
<string name="title" />
<int name="priceMin" />
<int name="priceMax" />
<int name="issuedByIDs" />
<int name="assigneeID" />
<int name="stationID" />
<int name="solarSystemID" />
<int name="regionID" />
<int name="itemTypeID" />
<int name="itemCategoryID" />
<int name="itemGroupID" />
</tupleInline>
</elementDef>
Should return a dict with these values:
|->contract = All the contract that fits the filters
|->items = All items for every contract that fits the filters
\->bids = All the bids for every contract that fits the filers
ContractMgrService::Handle_AcceptContract
The client will send these args:
<elementDef name="Call_AcceptContract">
<tupleInline>
<int name="contractID" default="0" none_marker="0" />
<bool name="unknown" none_marker="false" /><!-- isAccepted status from the contract? -->
</tupleInline>
</elementDef>
Should check first if the contract isAccepted, if not do this query;
UPDATE ContractInfo SET isAccepted=1, acceptorID=%d, status=1, dateAccepted="I64u" WHERE contractID=%d", call.client->GetCharacterID(), Win32Time_Now, contractID
Also the acceptor should pay the collateral
Should return true or false
ContractMgrService::Handle_CompleteContract
The client will send these args:
<elementDef name="Call_CompleteContract">
<tupleInline>
<int name="contractID" default="0" none_marker="0" />
<int name="status" default="0" none_marker="0" /><!-- contract status?-->
</tupleInline>
</elementDef>
status values:
status = 7 -> Failed
status = 6 -> Rejected
status = 4 -> Completed
The call should change the ChrContractInfo according to status( sent by the client ) and change the status value from ContractInfo WHERE contractID = contractID sent by the client
If status = complete contract you should check for all the items and conditions to accomplish before moving any money or changing the contract info
if( ( unknown != 7 ) && ( unknown != 6 ) && ( unknown != 4 ) )
{
if( forCorp )
{
sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numRequiresAttentionCorp=numRequiresAttentionCorp+1 WHERE characterID=%d", contractOwnerID);
}else{
sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numRequiresAttention=numRequiresAttention+1 WHERE characterID=%d", contractOwnerID);
}
}
if( unknown == 4 )
{
if( forCorp )sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numOutstandingContractsForCorp=numOutstandingContractsForCorp-1 WHERE characterID=%d", contractOwnerID);
else sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numOutstandingContractsNonCorp=numOutstandingContractsNonCorp-1 WHERE characterID=%d", contractOwnerID);
sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numOutstandingContracts=numOutstandingContracts-1 WHERE characterID=%d", contractOwnerID);
}
if( forCorp )sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numInProgressCorp=numInProgressCorp-1 WHERE characterID=%d", acceptorID);
else sDatabase.RunQuery(err, "UPDATE chrcontractinfo SET numInProgress=numInProgress-1 WHERE characterID=%d", acceptorID);
/**********************
* DATABASE INFO *
**********************/
ContractInfo:
Should have all the main data of the contract:
uint32 contractID;
uint32 issuerID; -> Character who created the contract
uint32 issuerCorpID; -> If the contract is for corp this will be the corporationID of the character who created this contract
uint32 type; -> contract type, is sent by the client
uint32 avail; -> Indicates if the contract is public or private
uint32 assigneeID; -> If the contract was asigned by the characterID to another character this will be the characterID who is assigned to
uint32 expiretime; -> Time in Win32 format of the duration of the contract
uint32 duration; -> Should be the number of days before contract expiration, anyway its send by the client as 0, maybe should be expiretime / Win32_Day
uint32 startStationID; -> Station where the contract was created
uint32 endStationID; -> Station where the items should be delivered if loan contract is selected
uint32 startSolarSystemID; -> Solar system where the contract was created
uint32 endSolarSystemID; -> Solar system where the items should be delivered if loan contract is selected
uint32 startRegionID; -> Region where the contract was created
uint32 endRegionID; -> Region where the items should be delivered if loan contract is selected
double price; -> Cost of the items or start of the bid if applicable
double reward; -> Money will be given when the contract is completed
double collateral; -> Quantity of ISK the acceptor will pay when accepting the contract
std::string title; -> Title of the contract, im not sure but i think this needs to be generated by the server
std::string description; -> Description of the contract sent by the client
bool forCorp; -> Indicates if the contract is for a corp or for a character
uint32 status; -> Status of the contract, 0 when contract is created
bool isAccepted; -> If the contract is accepted by someone this should be true
uint32 acceptorID; -> The characterID who accepted the contract
uint64 dateIssued; -> Date when the contract was created
uint64 dateExpired; -> Date when the contract will expire if not accepted
uint64 dateAccepted; -> If the contract is Accepted the date when the character accepted the contract
uint64 dateCompleted; -> When the contract was completed, before deletion
double volume; -> The total volume of the items if the contract is loan
bool requiresAttention; -> If the contract has recently changed and the creator needs to see these changes( like acception, rejection, etc )this should be true, when the creator sees the changes this should be false
uint32 allianceID; -> AllianceID of the character who created the contract
uint32 issuerWalletKey; -> Not sure how this should work as is part of the corporation system
uint32 crateID; -> ID of the "crate/cargo container ?" where the items are placed
ContractItems:
Should have all the main data of the items, and some info of the blueprint( if applicable )
uint32 id; -> Indexing purposes
uint32 itemID; -> If the item is given by the contract creator should point to the itemID of the item
uint32 contractID; -> ID
uint32 quantity; -> Quantity of this item
uint32 flag; -> Normally Hangar Flag, indicates where the item was got
uint32 typeID; -> typeID of the item in invTypes
uint32 ownerID; -> If the item is given by the contract creator should point to the characterID who created the contract
uint32 inCrate; -> ID of the crate where the item is if applicable
uint32 bpRuns; -> blueprint specific
uint32 parentID; -> Dont know what this is used for, also blueprint specific ?
bool get; -> if the item is requested or given by the contract creator
ContractBids:
Not sure if this is correct, but should be something like this:
uint32 bidID; -> Indexing purposes
uint32 contractID; -> contractID to wich the bid is
uint32 issuerID; -> characterID of the bidder
double quantity; -> Quantity of ISK bidded
uint32 issuerCorpID; -> corporationID of the bidder
uint32 issuerStationID; -> stationID of the bidder
uint32 issuerSolarSystemID; -> solarSystemID of the bidder
uint32 issuerRegionID; -> regionID of the bidder
ChrContractInfo:
These fields are completely confirmed:
uint32 characterID;
uint32 numOutstandingContractsNonCorp;
uint32 numOutstandingContractsForCorp;
uint32 numOutstandingContracts;
uint32 numContractsLeft;
uint32 numRequiresAttention;
uint32 numRequiresAttentionCorp;
uint32 numAssignedTo;
uint32 numAssignedToCorp;
uint32 numBiddingOn;
uint32 numInProgress;
uint32 numBiddingOnCorp;
uint32 numInProgressCorp;