code.vegaprotocol.io/vega@v0.79.0/datanode/entities/game.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package entities
    17  
    18  import (
    19  	"encoding/json"
    20  	"fmt"
    21  
    22  	"code.vegaprotocol.io/vega/libs/num"
    23  	v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2"
    24  	"code.vegaprotocol.io/vega/protos/vega"
    25  )
    26  
    27  type _Game struct{}
    28  
    29  type GameID = ID[_Game]
    30  
    31  type Game struct {
    32  	ID            GameID
    33  	Epoch         uint64
    34  	Participants  uint64
    35  	Entities      []GameEntity
    36  	RewardAssetID AssetID
    37  }
    38  
    39  func (g Game) Cursor() *Cursor {
    40  	gc := GameCursor{
    41  		EpochID: g.Epoch,
    42  		GameID:  g.ID,
    43  	}
    44  	return NewCursor(gc.String())
    45  }
    46  
    47  func (g Game) ToProtoEdge(_ ...any) (*v2.GameEdge, error) {
    48  	return &v2.GameEdge{
    49  		Node:   g.ToProto(),
    50  		Cursor: g.Cursor().Encode(),
    51  	}, nil
    52  }
    53  
    54  type GameCursor struct {
    55  	EpochID uint64
    56  	GameID  GameID
    57  }
    58  
    59  func (gc GameCursor) String() string {
    60  	bs, err := json.Marshal(gc)
    61  	if err != nil {
    62  		panic(fmt.Errorf("could not marshal game cursor %v", err))
    63  	}
    64  	return string(bs)
    65  }
    66  
    67  func (gc *GameCursor) Parse(cursorString string) error {
    68  	if cursorString == "" {
    69  		return nil
    70  	}
    71  	return json.Unmarshal([]byte(cursorString), gc)
    72  }
    73  
    74  type GameEntity interface {
    75  	IsGameEntity()
    76  }
    77  
    78  type TeamGameParticipation struct {
    79  	TeamID               TeamID
    80  	MembersParticipating []*IndividualGameEntity
    81  }
    82  
    83  func (t TeamGameParticipation) ToProto() *v2.TeamGameParticipation {
    84  	members := make([]*v2.IndividualGameEntity, len(t.MembersParticipating))
    85  	for i, member := range t.MembersParticipating {
    86  		members[i] = member.ToProto()
    87  	}
    88  	return &v2.TeamGameParticipation{
    89  		TeamId:               t.TeamID.String(),
    90  		MembersParticipating: members,
    91  	}
    92  }
    93  
    94  type TeamGameEntity struct {
    95  	Team                      TeamGameParticipation
    96  	Rank                      uint64
    97  	Volume                    num.Decimal
    98  	RewardMetric              vega.DispatchMetric
    99  	RewardEarned              *num.Uint
   100  	RewardEarnedQuantum       *num.Uint
   101  	TotalRewardsEarned        *num.Uint
   102  	TotalRewardsEarnedQuantum *num.Uint
   103  }
   104  
   105  func (*TeamGameEntity) IsGameEntity() {}
   106  func (t *TeamGameEntity) ToProto() *v2.TeamGameEntity {
   107  	return &v2.TeamGameEntity{
   108  		Team:                      t.Team.ToProto(),
   109  		Rank:                      t.Rank,
   110  		Volume:                    t.Volume.String(),
   111  		RewardMetric:              t.RewardMetric,
   112  		RewardEarned:              t.RewardEarned.String(),
   113  		TotalRewardsEarned:        t.TotalRewardsEarned.String(),
   114  		RewardEarnedQuantum:       t.RewardEarnedQuantum.String(),
   115  		TotalRewardsEarnedQuantum: t.TotalRewardsEarnedQuantum.String(),
   116  	}
   117  }
   118  
   119  type IndividualGameEntity struct {
   120  	Individual                string
   121  	Rank                      uint64
   122  	Volume                    num.Decimal
   123  	RewardMetric              vega.DispatchMetric
   124  	RewardEarned              *num.Uint
   125  	RewardEarnedQuantum       *num.Uint
   126  	TotalRewardsEarned        *num.Uint
   127  	TotalRewardsEarnedQuantum *num.Uint
   128  }
   129  
   130  func (*IndividualGameEntity) IsGameEntity() {}
   131  
   132  func (i *IndividualGameEntity) ToProto() *v2.IndividualGameEntity {
   133  	return &v2.IndividualGameEntity{
   134  		Individual:                i.Individual,
   135  		Rank:                      i.Rank,
   136  		Volume:                    i.Volume.String(),
   137  		RewardMetric:              i.RewardMetric,
   138  		RewardEarned:              i.RewardEarned.String(),
   139  		TotalRewardsEarned:        i.TotalRewardsEarned.String(),
   140  		RewardEarnedQuantum:       i.RewardEarnedQuantum.String(),
   141  		TotalRewardsEarnedQuantum: i.TotalRewardsEarnedQuantum.String(),
   142  	}
   143  }
   144  
   145  func (g Game) ToProto() *v2.Game {
   146  	gg := &v2.Game{
   147  		Id:            g.ID.String(),
   148  		RewardAssetId: g.RewardAssetID.String(),
   149  		Epoch:         g.Epoch,
   150  		Participants:  g.Participants,
   151  		Entities:      nil,
   152  	}
   153  	teamEntities := make([]*v2.TeamGameEntity, 0)
   154  	individualEntities := make([]*v2.IndividualGameEntity, 0)
   155  	for _, e := range g.Entities {
   156  		switch entity := e.(type) {
   157  		case *TeamGameEntity:
   158  			teamEntities = append(teamEntities, entity.ToProto())
   159  		case *IndividualGameEntity:
   160  			individualEntities = append(individualEntities, entity.ToProto())
   161  		}
   162  	}
   163  	if len(teamEntities) > 0 {
   164  		gg.Entities = &v2.Game_Team{
   165  			Team: &v2.TeamGameEntities{
   166  				Team: teamEntities,
   167  			},
   168  		}
   169  		return gg
   170  	}
   171  	gg.Entities = &v2.Game_Individual{
   172  		Individual: &v2.IndividualGameEntities{
   173  			Individual: individualEntities,
   174  		},
   175  	}
   176  	return gg
   177  }