syntax = "proto3";

import "google/protobuf/timestamp.proto";

package Klang.Seed.Services.EventLogs.Deployment;

// Event Types
message Event {
  oneof eventAttributes {
    PlayerSessionStart playerSessionStart = 1000;
    PlayerSessionEnd playerSessionEnd = 1001;
    PlayerLogin PlayerLogin = 1002;
    CharacterBorn CharacterBorn = 1003;
    CharacterDied CharacterDied = 1004;
    ActivityCompleted ActivityCompleted = 1005;
    SkillLevelUp SkillLevelUp = 1006;
    SystemWorkerProcessStarted SystemWorkerProcessStarted = 1007;
    PlayerNotificationSent PlayerNotificationSent = 1008;
    XpGained XpGained = 1009;
    HologramMaterialized HologramMaterialized = 1010;
    EntityPackaged EntityPackaged = 1011;
    EntityDestroyed EntityDestroyed = 1012;
    StatusEffectAdded StatusEffectAdded = 1013;
    StatusEffectRemoved StatusEffectRemoved = 1014;
    ClientPerformance ClientPerformance = 1015;
    ProductionEntryUpdated ProductionEntryUpdated = 1016;
    ProductionFinished ProductionFinished = 1017;
    EntityDismantled EntityDismantled = 1023; 
    ResourceGainedFromProduction ResourceGainedFromProduction = 1024;
    ResourceGainedFromHarvest ResourceGainedFromHarvest = 1025;
    ProductionOrderComplete ProductionOrderComplete = 1026;
    EnterLeaveProductionArea EnterLeaveProductionArea = 1027;
    InventoryState InventoryState = 1028;
    ExploreFogOfWarArea ExploreFogOfWarArea = 1029;
    InventoryItemState InventoryItemState = 1031;
    TutorialTaskFinished TutorialTaskFinished = 1032;
    TutorialTaskStepFinished TutorialTaskStepFinished = 1033;
    OnboardingStarted OnboardingStarted = 1034;
    OnboardingFinished OnboardingFinished = 1035;
    PlayerAddedToFavorites PlayerAddedToFavorites = 1036;
    PlayerRemovedFromFavorites PlayerRemovedFromFavorites = 1037;
    DirectMessageSent DirectMessageSent = 1038;
    PlayerBalanceChange PlayerBalanceChange = 1039;
    RelationshipChange RelationshipChange = 1040;
    ThoughtStateChange ThoughtStateChange = 1041;
    EmotionalStateChange EmotionalStateChange = 1042;
    SeedlingJobAssignment SeedlingJobAssignment = 1043;
    SeedlingScheduleAssignment SeedlingScheduleAssignment = 1044;
    UIViewInteraction UIViewInteraction = 1045;
    DesireGain DesireGain = 1046;
    DesireLost DesireLost = 1047;
    InfluenceChanged InfluenceChanged = 1048;
    RelationshipChanged RelationshipChanged = 1049;
    EntityCreated EntityCreated = 1050;
    StorageChanged StorageChanged = 1051;
  }
}

message PlayerSessionStart {
  string version = 1;
  string build = 2;
  string branch = 3;
  bool developmentBuild = 4;
  string deviceUniqueIdentifier = 5;
  int32 graphicsDeviceID = 6;
  string graphicsDeviceName = 7;
  string graphicsDeviceType = 8;
  string graphicsDeviceVendor = 9;
  string graphicsDeviceVendorID = 10;
  string graphicsDeviceVersion = 11;
  int32 graphicsMemorySize = 12;
  int32 graphicsShaderLevel = 13;
  string operatingSystem = 14;
  string operatingSystemFamily = 15;
  int32 processorCount = 16;
  int32 processorFrequency = 17;
  string processorType = 18;
  int32 systemMemorySize = 19;
}

message PlayerSessionEnd {
  int64 userId = 1;
  double sessionLengthTotal = 2;
  double sessionLengthInFocus = 3;
  google.protobuf.Timestamp sessionStartTime = 4;
  google.protobuf.Timestamp sessionEndTime =  5;
  int64 globalSessionNumber = 6;
  int64 deploymentSessionNumber = 7;
  bool hasDevRole = 8;
  bool hasAdminRole = 9;
}

// Deprecated: not called on server
message PlayerLogin {
  int64 userId = 1;
  string username =  2;
  int64 colonyId = 3;
  int64 playerId = 4;
  int64 globalSessionNumber = 5;
  int64 deploymentSessionNumber = 6;
  string remoteIp = 7;
  bool hasDevRole = 8;
  bool hasAdminRole = 9;
  string clientSessionId = 10;
}

message CharacterBorn {
  int64 userId = 1;
  int64 characterId = 2;
  int64 colonyId = 3;
  string name = 4;
  int32 initialAge = 5;
  bool isMale = 6;
  int64 simTime = 7;
}

message CharacterDied {
  int64 characterId = 1;
  int64 simTime = 2;
  int64 characterAge = 3;
  int64 playerId = 4;
  int64 colonyId = 5;
  int64 userId = 6;
}

message ActivityCompleted {
  enum ActivityResult {
    None = 0;
    CriticalSuccess = 1;
    Success = 2;
    Failure = 3;
    CriticalFailure = 4;
    Interrupt = 5;
  }

  enum EventOrigin {
    FinishCurrentActivity = 0;
    AbortCurrentActivity = 1;
    FailCurrentActivity = 2;
  }

  int64 characterId = 1;
  string activityType = 2;
  float totalDuration = 3;
  float effortDuration = 4;
  ActivityResult activityResult = 5;
  string skillType = 6;
  int32 xpGained = 7;
  int32 skillLevel = 8;
  int64 issuerId = 9;
  bool isForced = 10;
  int32 difficulty = 11;
  EventOrigin eventOrigin = 12;
  int64 simTime = 13;
  string agentGameType = 14;
  string issuerGameType = 15;
  int64 positionX = 16;
  int64 positionY = 17;
  int64 positionZ = 18;
  int64 simDuration = 19;
  string activityGuid = 20;
  string scheduleBlockGuid = 21;
  int64 userId = 22;
}

message XpGained {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 simTime = 3;
  int64 characterId = 4;
  string activityGuid = 5;
  int64 skillId = 6;
  string skillName = 7;
  int32 gainedXP = 8;
  int32 currentXP = 9;
  int32 currentSkillLevel = 10;
  bool skillLevelUp = 11;
  int64 userId = 12;
}

// Deprecated: not called on server
message StatusEffectAdded {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 simTime = 3;
  string gameType = 4;
  int64 entityId = 5;
  string effectId = 6;
  int64 userId = 7;
}

// Deprecated: not called on server
message StatusEffectRemoved {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 simTime = 3;
  string gameType = 4;
  int64 entityId = 5;
  string effectId = 6;
  int64 userId = 7;
}

// Deprecated: not called on server
message HologramMaterialized {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 simTime = 3;
  string gameType = 4;
  int64 entityId = 5;
  int64 userId = 6;
}

// NOTE: Obsolete: only used when packaging on the spot, only used by the activity "Package" on right click
message EntityPackaged {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 simTime = 3;
  string gameType = 4;
  int64 entityId = 5;
  int64 pileId = 6;
  int64 userId = 7;
}

// Triggered when an entity is destroyed (not just returned to stockpile). Should mainly be a GM event
message EntityDestroyed {
  int64 simTime = 1;
  string gameType = 2;
  int64 entityId = 3;
  int64 pileId = 4;
  int64 userId = 5;
}

// Deprecated: not called on server
message SkillLevelUp {
  int64 characterId = 1;
  string activityType = 2;
  string skillType = 3;
  int32 newLevel = 4;
  int32 xpGained = 5;
  int64 simTime = 6;
  int64 playerId = 7;
  int64 colonyId = 8;
  int64 userId = 9;
}

message SystemWorkerProcessStarted {
  string processType = 1;
  string processIdentifier = 2;
  string processDescription = 3;
  string hostname = 4;
}

message PlayerNotificationSent {
  int64 playerId = 1;
  int64 associatedEntityId = 2;
  string associatedEntityGameType = 3;
  string content = 4;
  string notification = 5;
  int64 simTime = 6;
  google.protobuf.Timestamp timestamp = 7;
  int64 userId = 8;
}

message ClientPerformance {
  enum BatteryStatus {
    Unspecified = 0;
    Unknown = 1;
    Charging = 2;
    Discharging = 3;
    NotCharging = 4;
    Full = 5;
  }

  float frametimeAvg = 1;
  float frametimeMax = 2;
  float frametimeMin = 3;
  float frametimePercentile50 = 4;
  float frametimePercentile90 = 5;
  float frametimePercentile99 = 6; 
  float frametimePercentile999 = 7; 
  float frameCount = 8; 
  float sampleDuration = 9;
  int32 renderWidth = 10;
  int32 renderHeight = 11;
  int32 graphicsDeviceVendorID = 12;
  int32 graphicsDeviceID = 13;
  string gameMode = 14;
  float processTime = 15;

  int64 setPassCallsAvg = 20;
  int64 setPassCallsMax = 21;
  int64 setPassCallsMin = 22;

  int64 drawCallsAvg = 30;
  int64 drawCallsMax = 31;
  int64 drawCallsMin = 32;

  int64 batchesAvg = 40;
  int64 batchesMax = 41;
  int64 batchesMin = 42;

  int64 verticesAvg = 50;
  int64 verticesMax = 51;
  int64 verticesMin = 52;

  int64 trianglesAvg = 60;
  int64 trianglesMax = 61;
  int64 trianglesMin = 62;

  float bytesSentAvg = 70;
  float bytesSentMin = 71;
  float bytesSentMax = 72;
  float bytesSent50 = 73;  
  float bytesSent90 = 74;
  float bytesSent99 = 75;

  float bytesRecievedAvg = 80;
  float bytesRecievedMin = 81;
  float bytesRecievedMax = 82;
  float bytesRecieved50 = 83;  
  float bytesRecieved90 = 84;
  float bytesRecieved99 = 85;

  float totalMemoryAvg = 90;
  float totalMemoryMin = 91;
  float totalMemoryMax = 92;

  float gfxMemoryAvg = 95;
  float gfxMemoryMin = 96;
  float gfxMemoryMax = 97;

  float systemMemoryAvg = 100;
  float systemMemoryMin = 101;
  float systemMemoryMax = 102;
  
  float NetworkRoundTripTime = 110;
  float NetworkRoundTripTimeVariance = 111;

  string processorType = 120;
  int32 processorCount = 121;
  int32 processorFrequency = 122;
  int32 systemMemorySize = 123;
  BatteryStatus batteryStatus  = 124;
  
  string graphicsDeviceVendor = 130;
  string graphicsDeviceName = 131;
  int32 graphicsMemorySize = 132;
  int32 displayCount = 133;
  int32 displayWidth = 134;
  int32 displayHeight = 135;
  float displayRefreshRate = 136;
  int32 displayVSyncCount = 137;
  
  string operatingSystem = 140;
}

message OnboardingStarted {
  int64 userId = 1;
  string username = 2;
}

message OnboardingFinished {
  int64 userId = 1;
  string username = 2;
}

message TutorialTaskFinished {
  int64 entityId = 1;
  string taskName = 2;
  google.protobuf.Timestamp taskStartTimestamp = 3;
}

message TutorialTaskStepFinished {
  int64 entityId = 1;
  string TaskName = 2;
  int32 stepIndex = 3;
  google.protobuf.Timestamp stepStartTimestamp = 4;
}

// Deprecated: not called on server 
// Triggered when the player queues or changes a production
message ProductionEntryUpdated {
  int64 playerId = 1;
  int64 entityId = 2;
  int64 entryId = 3;
  string productionEntryName = 4; // Example: BP_PLAXIN
  int32 productionEntryAmount = 5; // Example: 5
  int64 userId = 6;
}

// Deprecated: not called on server
// Triggered when a production (successfully) finishes
message ProductionFinished {
  int64 playerId = 1;
  int64 entityId = 2;
  int64 entryId = 3;
  string productionEntryName = 4; // Example: BP_PLAXIN
  int64 userId = 5;
}

// Triggered when a player's Seedling returns an entity to stockpile
message EntityDismantled {
  int64 playerId = 1;
  int64 entityId = 2;
  string gameType = 3;
  int64 userId = 4;
}

// Deprecated: not called on server
// Triggered when a resource is spawned from a production
message ResourceGainedFromProduction {
  int64 playerId = 1;
  string resourceGameType = 2; // Example: PLAXIN
  string producerGameType = 3;
  int32 amount = 4;
  int64 userId = 5;
}

// Deprecated: in HarvestableSystem: not used anymore
// Triggered when a resource is spawned from harvesting a static entity in the world
message ResourceGainedFromHarvest {
  int64 playerId = 1;
  string resourceGameType = 2; // Example: WOOD
  string harvestedGameType = 3; // Example: TREE
  int32 amount = 4;
  int64 userId = 5;
}

// Deprecated: not called on server 
// Triggered when a "Do X Times" production order in the Production Overview was completed
// Not to be confused with "ProductionFinished" event which is triggered when a single machine finishes a production cycle
message ProductionOrderComplete {
  int64 playerId = 1;
  int64 productionAreaId = 2;
  string blueprintGameType = 3; // Example: BP_PLAXIN
  string producerGameType = 4; // Example: PLAXIN_MIXER
  int32 amount = 5;
  int64 userId = 6;
}

// Deprecated: in ProductionAreaTelemetrySystem: not used anymore
// Triggered when the character leaves the production area, this will also create a list 
message EnterLeaveProductionArea {
  enum EventType {
    Enter = 0;
    Leave = 1;
  }
  
  EventType eventType = 1;
  int64 characterId = 2;
  int64 playerId = 4;
  string enterLeaveKey = 5;
  int64 userId = 6;
}

// Deprecated: in ProductionAreaTelemetrySystem: not used anymore
message InventoryState {
  string enterLeaveKey = 1;
  string gameType = 2;
  int32 amount = 3;
}

// Deprecated: in ExploredAreasInfluencerServerSystem: not used anymore
message ExploreFogOfWarArea {
  int64 revealingEntityId = 1;
  int64 playerId = 2;
  int32 gridPosX = 3;
  int32 gridPosY = 4;
  int64 userId = 5;
}

// Deprecated: not called on server
message InventoryItemState {
    string stateKey = 1;
    string type = 2;
    int32 amount = 3;
}

// Deprecated: in PlayerStateSystem: not used anymore
// Triggered when a player adds another player to their favorites
message PlayerAddedToFavorites {
  int64 playerId = 1;
  int64 favoritePlayerId = 2;
  int64 userId = 3;
}

// Deprecated: in PlayerStateSystem: not used anymore
// Triggered when a player removes another player from their favorites
message PlayerRemovedFromFavorites {
  int64 playerId = 1;
  int64 favoritePlayerId = 2;
  int64 userId = 3;
}

// Triggered when a player sends a direct message to another player
message DirectMessageSent {
  int64 playerId = 1;
  int64 receivingPlayerId = 2;
  bool receiverIsFavorite = 3;
  int64 userId = 4;
}

// Triggered when the player's balance changes due to a purchase, sale, entry fee payment or a Seedling earning their wage.
// If applicable, the "items" field will contain the purchased or sold gametypes and their amounts.
message PlayerBalanceChange {
  enum BalanceChangeReason {
    SeedlingWage = 0;
    ItemPurchase = 1;
    ItemSale = 2;
    EntryFee = 3;
    SeedlingEmployerPaidWage = 4;
    PaidRent = 5;
    HomePurchase = 6;
    HomeSale = 7;
    UniversityAccess = 8;
    Reward = 9;
    SubscriptionFee = 10;
    PlotPurchase = 11;
    PlotSale = 12;
    SeedlingPurchase = 13;
    InitialWalletBalance = 14;
  }

  int64 playerId = 1;
  int64 colonyId = 2;
  int64 simTime = 3;
  int64 newBalance = 4;
  int32 balanceChange = 5;
  BalanceChangeReason reason = 6;
  string itemType = 7;
  int32 itemAmount = 8;
  int64 userId = 9;
}

// Triggered when the relationship between two seedlings changes due to a multi-agent activity
message RelationshipChange {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 simTime = 3;
  int64 characterId = 4;
  int64 otherCharacterId = 6;
  string activityGuid = 5;
  float newValue = 7;
  float valueChange = 8;
  bool hasLoverConnection = 9;
  bool hasWorkConnection = 10;
  int64 userId = 11;
}

// Triggered when a thought is triggered through an activity
message ThoughtStateChange {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 characterId = 3;
  int64 simTime = 4;
  int64 thoughtId = 5;  // from GDE
  string activityGuid = 6;
  int64 userId = 7;
}

// Deprecated: not called on server
// Triggered when the emotional state of a character changes
message EmotionalStateChange {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 characterId = 3;
  int64 simTime = 4;
  int64 emotionId = 5;
  int64 userId = 6;
}

// Triggered when one of the views defined in ViewType enum is closed
message UIViewInteraction {
  enum UIType {
    None = 0;
    Calendar = 1;
    Schedule = 2;
    Employment = 3;
    Production = 4;
    Deliveries = 5;
    Relationships = 6; //?
    Thoughts = 7;
    Traits = 8;
    Skills = 9;
    Desires = 10;
    SeedlingPortrait = 11; //?
    Shop = 12;
    Chat = 13;
  }

  int64 playerId = 1;
  int64 simTime = 2;
  double durationOpened = 3;
  UIType uiType = 4;
  int64 characterId = 5; // 0 for character-agnostic UI
  int64 userId = 6;
}

// Triggered when a Seedling is assigned to or removed from a job position.
message SeedlingJobAssignment {
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 characterId = 3;
  int64 jobId = 4;  // from GDE
  string jobTitle = 5;
  int64 userId = 6;
}

// Triggered when a player creates or deletes a new event.
message SeedlingScheduleAssignment {
  enum ScheduleChangeType {
    SlotAdded = 0;
    SlotRemoved = 1;
  }
  int64 playerId = 1;
  int64 colonyId = 2;
  int64 characterId = 3;
  int64 simTime = 4;
  string targetLocation = 5;
  int64 hostId = 6;
  int64 guestId = 7;
  int64 simTimeToNextOccurrence = 8;
  int64 simTimeDuration = 9;
  string scheduleBlockGuid = 10;
  ScheduleChangeType scheduleChangeType = 11;
  int64 userId = 12;
}

message DesireGain {
  int64 simTime = 1;
  int64 colonyId = 2;  
  int64 playerId = 3;
  
  int64 characterId = 4;
  
  int64 desireId = 5;
  int64 desireLifetime = 6;  
}

message DesireLost {
  enum DesireResult {
    Success = 0;
    SuccessWithMilestone = 1;
    Failure = 2;
  }

  int64 simTime = 1;
  int64 colonyId = 2;  
  int64 playerId = 3;
  
  int64 characterId = 4;
  
  int64 desireId = 5;
  int64 desireLifetime = 6;
  DesireResult desireResult = 7;  
}

message InfluenceChanged {
  int64 simTime = 1;
  int64 colonyId = 2;  
  int64 playerId = 3;
  
  int64 characterId = 4;

  int64 influenceValue = 5;
  int32 influenceChangedAmount = 6;
}

message RelationshipChanged {
  int64 simTime = 1;
  int64 colonyId = 2;  
  int64 playerId = 3;
  
  int64 characterId = 4;

  int64 relationshipTargetId = 5;
  string relationshipType = 6;
  float relationshipValue = 7;
  float relationshipChangedAmount = 8;
}

// Triggered when an entity is created, whether by a player or the game: expect a lot of events when a world/sector is launched, but just once
message EntityCreated {
  int64 playerId = 1;
  int64 entityId = 2;
  string gameType = 3;
  float positionX = 4;
  float positionY = 5;
  float positionZ = 6;
}

// Triggered when an item is added or removed from storage. Removals are represented by negative quantities.
message StorageChanged {
  int64 entityId = 1;
  string itemName = 2;
  int32 itemAmountChange = 3;
}

// Triggered when the player moves an entity inside a house
message EntityMovedInHouse {
  int64 playerId = 1;
  int64 entityId = 2;
  string gameType = 3;
  float positionX = 4;
  float positionY = 5;
  float positionZ = 6;
  string clientSessionId = 7;
}