open-match.dev/open-match@v1.8.1/examples/functions/golang/soloduel/mmf/matchfunction.go (about) 1 // Copyright 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package mmf provides a sample match function that uses the GRPC harness to set up 1v1 matches. 16 // This sample is a reference to demonstrate the usage of the GRPC harness and should only be used as 17 // a starting point for your match function. You will need to modify the 18 // matchmaking logic in this function based on your game's requirements. 19 package mmf 20 21 import ( 22 "fmt" 23 "log" 24 "time" 25 26 "google.golang.org/grpc" 27 "open-match.dev/open-match/pkg/matchfunction" 28 "open-match.dev/open-match/pkg/pb" 29 ) 30 31 var ( 32 matchName = "a-simple-1v1-matchfunction" 33 ) 34 35 // matchFunctionService implements pb.MatchFunctionServer, the server generated 36 // by compiling the protobuf, by fulfilling the pb.MatchFunctionServer interface. 37 type matchFunctionService struct { 38 grpc *grpc.Server 39 queryServiceClient pb.QueryServiceClient 40 port int 41 } 42 43 func makeMatches(poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) { 44 tickets := map[string]*pb.Ticket{} 45 for _, pool := range poolTickets { 46 for _, ticket := range pool { 47 tickets[ticket.GetId()] = ticket 48 } 49 } 50 51 var matches []*pb.Match 52 53 t := time.Now().Format("2006-01-02T15:04:05.00") 54 55 thisMatch := make([]*pb.Ticket, 0, 2) 56 matchNum := 0 57 58 for _, ticket := range tickets { 59 thisMatch = append(thisMatch, ticket) 60 61 if len(thisMatch) >= 2 { 62 matches = append(matches, &pb.Match{ 63 MatchId: fmt.Sprintf("profile-%s-time-%s-num-%d", matchName, t, matchNum), 64 MatchProfile: matchName, 65 MatchFunction: matchName, 66 Tickets: thisMatch, 67 }) 68 69 thisMatch = make([]*pb.Ticket, 0, 2) 70 matchNum++ 71 } 72 } 73 74 return matches, nil 75 } 76 77 // Run is this match function's implementation of the gRPC call defined in api/matchfunction.proto. 78 func (s *matchFunctionService) Run(req *pb.RunRequest, stream pb.MatchFunction_RunServer) error { 79 // Fetch tickets for the pools specified in the Match Profile. 80 log.Printf("Generating proposals for function %v", req.GetProfile().GetName()) 81 82 poolTickets, err := matchfunction.QueryPools(stream.Context(), s.queryServiceClient, req.GetProfile().GetPools()) 83 if err != nil { 84 log.Printf("Failed to query tickets for the given pools, got %s", err.Error()) 85 return err 86 } 87 88 // Generate proposals. 89 proposals, err := makeMatches(poolTickets) 90 if err != nil { 91 log.Printf("Failed to generate matches, got %s", err.Error()) 92 return err 93 } 94 95 log.Printf("Streaming %v proposals to Open Match", len(proposals)) 96 // Stream the generated proposals back to Open Match. 97 for _, proposal := range proposals { 98 if err := stream.Send(&pb.RunResponse{Proposal: proposal}); err != nil { 99 log.Printf("Failed to stream proposals to Open Match, got %s", err.Error()) 100 return err 101 } 102 } 103 104 return nil 105 }