syntax = "proto3";

// 礼物事件 V2
// @since 发现于 Apr 24, 2025，可能出现的更早，只有某些特定的直播间内会出现
// @example 测试直播间 https://live.bilibili.com/1883358196
message SendGiftV2 {
  // Baisc user info
  message UInfo {
    uint64 uid = 1;

    Base base = 2;
    message Base {
      string name = 1;
      string face = 2;
      optional int32 name_color = 3;
      optional bool is_mystery = 4;
    }

    optional Medal medal = 3;
    message Medal {
      string name = 1;
      int64 level = 2;
      int64 color_start = 3;
      int64 color_end = 4;
      int64 color_border = 5;
      int64 color = 6;
      int64 id = 7;
      int32 typ = 8;
      int64 is_light = 9;
      int64 ruid = 10;
      int64 guard_level = 11;
      int64 score = 12;
      // Jul 15, 2026, 11:50:26 AM PDT: 现在似乎不会返回 guard_icon 了
      optional string guard_icon = 13;
    }

    optional Wealth wealth = 4;
  }

  // Basic wealth info
  message Wealth {
    int64 level = 1;
  }

  uint64 uid = 1;
  string uname = 2;
  string face = 3;
  optional string name_color = 4;
  optional int64 guard_level = 5;
  optional int64 svga_block = 6;

  optional SendMaster send_master = 7;
  message SendMaster {
    uint64 uid = 1;
    string uname = 2;
  }

  optional Medal medal_info = 8;
  message Medal {
    // 对应主播 UID
    uint64 ruid = 1;
    // 勋章等级
    uint32 level = 5;
    // 勋章名称
    string name = 6;
    uint32 is_lighted = 11;
    uint32 guard_level = 12;
  }

  optional BlindGift blind_gift = 9;
  message BlindGift {
    int64 blind_gift_config_id = 1;
    // 盲盒 id，非礼物 id
    // @example 32649
    int64 original_gift_id = 2;
    // 盲盒名称
    // @example 星月盲盒
    string original_gift_name = 3;
    optional int64 from = 4;
    // 盲盒动作
    // @example 爆出
    string gift_action = 5;
    // 盲盒价格，非礼物爆出的虚拟价格
    // @example 5000
    int64 original_gift_price = 6;
    // 盲盒爆出的虚拟价格，但是 protobuf 中似乎不存在，需要从下方的 GiftItem 中判断
    optional int64 gift_tip_price = 7;
  }

  // Guessed based on `SEND_GIFT`
  repeated GiftItem gift_item = 10;
  message GiftItem {
    uint32 gift_id = 1;
    string gift_name = 2;
    uint32 num = 3;
    uint64 demarcation = 4;
    // 礼物价格，单位金瓜子，5200 代表 5.2 元
    // 当此处为盲盒礼物时，此处显示的是虚拟价格（经验值）
    // @example 5200
    uint64 price = 5;
    // 通常等于 `price`
    // @example 5200
    uint64 discount_price = 6;
    // 硬币实际价格
    // 当此处为盲盒礼物时，此处显示的是实际支付价格
    // @example 5000
    uint64 total_coin = 7;
    // @example `gold`
    string coin_type = 8;
    // @example `4658866727424159744`
    string tid = 9;
    uint64 timestamp = 10;
    uint64 super_batch_gift_num = 11;
    // @example `batch:gift:combo_id:2763:3546687211572101:31036:1751704815.1741`
    string batch_combo_id = 12;
    uint64 combo_resources_id = 13;
    // 当此处为盲盒礼物时，此处显示的是虚拟价格（经验值）
    uint64 combo_total_coin = 14;
    uint64 combo_stay_time = 15;
    float magnification = 16;
    optional bool show_batch_combo_send = 17;
    // @example `投喂`
    string action = 18;
    optional int64 effect_block = 19;
    optional int64 is_special_batch = 20;
    optional int64 float_sc_resource_id = 21;
    optional string tag_image = 22;
    optional int64 crit_prob = 23;
    uint64 rcost = 24;
    optional int64 test = 25;
    optional int64 face_effect_type = 26;
    optional int64 face_effect_id = 27;
    optional bool is_naming = 28;

    ReceiveUserInfo receive_user_info = 29;
    message ReceiveUserInfo {
      string uname = 1;
      uint64 uid = 2;
    }

    optional bool is_join_receiver = 30;

    optional BagGiftInfo bag_gift = 31;
    message BagGiftInfo {
      int32 show_price = 1;
      int64 price_for_show = 2;
    }

    repeated int64 gift_tag = 32;

    UInfo receiver_uinfo = 33;

    optional FaceEffectV2 face_effect_v2 = 34;
    message FaceEffectV2 {
      int64 id = 1;
      int64 type = 2;
    }

    GiftMaterialSnapShot gift_info = 35;
    message GiftMaterialSnapShot {
      string img_basic = 1;
      string webp = 2;
      int64 effect_id = 3;
      int64 has_imaged_gift = 4;
      optional string gif = 5;
    }

    // 盲盒爆出的虚拟价格
    // @example 5200
    optional int64 gift_tip_price = 36;
  }

  optional bool switch = 11;
  optional int64 test = 12;

  optional Wealth wealth = 13;

  optional GroupMedal group_medal = 14;
  message GroupMedal {
    int64 medal_id = 1;
    string name = 2;
    int64 is_lighted = 3;
  }

  optional UInfo sender_uinfo = 15;
}

// 互动事件
// @since Jul 4, 2025
message InteractWordV2 {
  uint64 uid = 1;
  string username = 2;
  uint32 msg_type = 5;
  uint32 room_id = 6;
  uint32 timestamp = 7;
  uint64 timestamp_ms = 8;

  // 粉丝牌
  optional Medal medal = 9;
  message Medal {
    uint64 ruid = 1;
    uint32 level = 2;
    string name = 3;
    int32 f4 = 4;
    int32 f5 = 5;
    int32 f6 = 6;
    int32 f7 = 7;
    uint32 is_lighted = 8;
    uint32 guard_level = 9;
    uint32 room_id = 12;
    int32 f13 = 13;
  }
  uint64 trigger_time = 15;
  uint32 guard_type = 16;
  int32 f17 = 17;

  // UInfo
  UInfo uinfo = 22;
  message UInfo {
    uint64 uid = 1;

    Base base = 2;
    message Base {
      string username = 1;
      string avatar = 2;
      string f3 = 3;
    }
    optional Medal medal = 3;
    message Medal {
      // @example 奶糖花
      string name = 1;
      // level
      uint32 level = 2;
      int32 color_start = 3;
      int32 color_end = 4;
      int32 color_border = 5;
      int32 color = 6;
      int32 id = 7;
      int32 f9 = 9;
      uint64 ruid = 10;
      int32 f11 = 11;
      int32 f12 = 12;
      optional string guard_icon = 13;
      // @example #4775EFCC
      uint32 v2_medal_color_start = 15;
      // @example #4775EFCC
      uint32 v2_medal_color_end = 16;
      // @example #58A1F8FF
      uint32 v2_medal_color_border = 17;
      // @example #FFFFFFFF
      uint32 v2_medal_text = 18;
      // @example #000B7099
      uint32 v2_medal_level = 19;
    }

    // 荣耀等级
    Wealth wealth = 4;
    message Wealth {
      uint32 level = 1;
      // @example ChronosWealth_5.png
      optional string icon = 2;
    }

    Message6 f6 = 6;
    message Message6 {
      int32 f1 = 1;
      // @example 2025-07-27 23:59:59
      string f2 = 2;
    }
  }

  optional RelationTail relation_tail = 23;
  message RelationTail {
    // @example https://i0.hdslb.com/bfs/live/b9de5d510125c6f14cd68391d5a4878fe16356b3.png
    string tail_icon = 1;
    // @example TA常看你的直播，但还没有关注
    string tail_guide_text = 2;
    // @example 1
    uint32 tail_type = 3;
  }
}

// 高能用户列表 v3
// @since Jul 5, 2025
message OnlineRankV3 {
  // @example online_rank
  string rank_type = 1;

  message OnlineList {
    uint64 uid = 1;
    string face = 2;
    // 贡献值，打赏电池数，string 格式😅
    string score = 3;
    string uname = 4;
    // 当前排名
    uint32 rank = 5;
    optional uint32 guard_level = 6;
    optional bool is_mystery = 7;

    // UInfo
    optional UInfo uinfo = 8;
    message UInfo {
      uint64 uid = 1;

      Base base = 2;
      message Base {
        string name = 1;
        string face = 2;
        uint32 name_color = 3;
        bool is_mystery = 4;

        // Not in use, commented out for simplicity
        // optional RiskCtrlInfo risk_ctrl_info = 5;
        // message RiskCtrlInfo {
        //   string name = 1;
        //   string face = 2;
        // }

        // Not in use, commented out for simplicity
        // optional OriginInfo origin_info = 6;
        // message OriginInfo {
        //   string name = 1;
        //   string face = 2;
        // }
      }

      optional Guard guard = 6;
      message Guard {
        uint32 level = 1;
        // @example 2025-08-30 23:59:59
        string expired_str = 2;
      }
    }
  }

  repeated OnlineList online_list = 3;
}
