Old Wiki:Contract System
Jump to navigation
Jump to search
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;