fork
Configure Feed
Select the types of activity you want to include in your feed.
A game about forced loneliness, made by TACStudios
fork
Configure Feed
Select the types of activity you want to include in your feed.
1using System;
2using System.Collections.Generic;
3using Unity.Multiplayer.Center.Questionnaire;
4using UnityEngine;
5
6namespace Unity.Multiplayer.Center.Recommendations
7{
8 /// <summary>
9 /// Contains all the architectural options that we offer to users, with a score specific to their answers.
10 /// This is the data that we show in the UI.
11 /// </summary>
12 [Serializable]
13 internal class RecommendationViewData
14 {
15 /// <summary>
16 /// NGO or N4E or Other
17 /// </summary>
18 public RecommendedSolutionViewData[] NetcodeOptions;
19
20 /// <summary>
21 /// Client hosted / dedicated server.
22 /// It comes with UGS services that we might or might not recommend
23 /// </summary>
24 public RecommendedSolutionViewData[] ServerArchitectureOptions;
25 }
26
27 /// <summary>
28 /// For each selection (netcode, hosting) model, there is a specific set of recommended packages
29 /// This class stores this information and provides access to it.
30 /// </summary>
31 [Serializable]
32 internal class SolutionsToRecommendedPackageViewData
33 {
34 [SerializeField] RecommendedPackageViewDataArray[] m_Packages;
35 public SolutionSelection[] Selections;
36
37 // Because we cannot serialize two-dimensional arrays
38 [Serializable]
39 internal struct RecommendedPackageViewDataArray
40 {
41 public RecommendedPackageViewData[] Packages;
42 }
43
44 public SolutionsToRecommendedPackageViewData(SolutionSelection[] selections, RecommendedPackageViewData[][] packages)
45 {
46 Debug.Assert(selections.Length == packages.Length, "Selections and packages must have the same length");
47 Selections = selections;
48 m_Packages = new RecommendedPackageViewDataArray[packages.Length];
49 for (var i = 0; i < packages.Length; i++)
50 {
51 m_Packages[i] = new RecommendedPackageViewDataArray {Packages = packages[i]};
52 }
53 }
54
55 public RecommendedPackageViewData[] GetPackagesForSelection(PossibleSolution netcode, PossibleSolution hosting)
56 {
57 return GetPackagesForSelection(new SolutionSelection(netcode, hosting));
58 }
59
60 public RecommendedPackageViewData[] GetPackagesForSelection(SolutionSelection selection)
61 {
62 var index = Array.IndexOf(Selections, selection);
63 return index < 0 ? Array.Empty<RecommendedPackageViewData>() : m_Packages[index].Packages;
64 }
65 }
66
67 /// <summary>
68 /// Base fields for things that we can recommend (typically a package or a solution).
69 /// </summary>
70 [Serializable]
71 internal class RecommendedItemViewData
72 {
73 /// <summary>
74 /// How much we want to recommend this item. With the score, this is what is modified by the recommender system.
75 /// The architecture option with the best score will be marked as MainArchitectureChoice, the other as SecondArchitectureChoice,
76 /// which enables us to highlight the recommended option.
77 /// </summary>
78 public RecommendationType RecommendationType;
79
80 /// <summary>
81 /// Item is part of the selection, because it was preselected or user selected it.
82 /// </summary>
83 public bool Selected;
84
85 /// <summary>
86 /// Optional: reason why this recommendation was made
87 /// </summary>
88 public string Reason;
89
90 /// <summary>
91 /// Url to feature documentation
92 /// </summary>
93 public string DocsUrl;
94
95 /// <summary>
96 /// Recommendation is installed and direct dependency
97 /// </summary>
98 public bool IsInstalledAsProjectDependency;
99
100 /// <summary>
101 /// Installed version number of a package
102 /// </summary>
103 public string InstalledVersion;
104 }
105
106 /// <summary>
107 /// Architectural solution (netcode or server architecture) that we offer. It comes with an optional main package and
108 /// associated recommended packages.
109 /// </summary>
110 [Serializable]
111 internal class RecommendedSolutionViewData : RecommendedItemViewData
112 {
113 public string Title;
114
115 public PossibleSolution Solution;
116
117 /// <summary>
118 /// How much of a match is this item. Computed by recommender system based on answers.
119 /// </summary>
120 public float Score;
121
122 /// <summary>
123 /// The main package to install for this solution (note that this might be null, e.g. for client hosted game)
124 /// </summary>
125 public RecommendedPackageViewData MainPackage;
126
127 public string WarningString;
128
129 public RecommendedSolutionViewData(RecommenderSystemData data, RecommendedSolution solution,
130 RecommendationType type, Scoring scoring, Dictionary<string, string> installedPackageDictionary)
131 {
132 if (!string.IsNullOrEmpty(solution.MainPackageId))
133 {
134 var mainPackageDetails = data.PackageDetailsById[solution.MainPackageId];
135 DocsUrl = string.IsNullOrEmpty(solution.DocUrl) ? mainPackageDetails.DocsUrl : solution.DocUrl;
136
137 if (installedPackageDictionary.ContainsKey(solution.MainPackageId))
138 {
139 InstalledVersion = installedPackageDictionary[solution.MainPackageId];
140 IsInstalledAsProjectDependency = PackageManagement.IsDirectDependency(solution.MainPackageId);
141 }
142
143 MainPackage = new RecommendedPackageViewData(mainPackageDetails, type, InstalledVersion);
144 }
145 else
146 {
147 DocsUrl = solution.DocUrl;
148 }
149
150 RecommendationType = type;
151 Title = solution.Title;
152 Reason = scoring?.GetReasonString();
153 Score = scoring?.TotalScore ?? 0f;
154 Selected = RecommendationType.IsRecommendedSolution();
155
156 Solution = solution.Type;
157 }
158 }
159
160 /// <summary>
161 /// Single package that is part of a recommendation.
162 /// </summary>
163 [Serializable]
164 internal class RecommendedPackageViewData : RecommendedItemViewData
165 {
166 public string PackageId;
167
168 public string Name;
169
170 public string PreReleaseVersion;
171
172 /// <summary>
173 /// A short description of the feature.
174 /// </summary>
175 public string ShortDescription = "Short description not added yet";
176
177 public RecommendedPackageViewData(PackageDetails details, RecommendationType type, string installedVersion=null, string reason = null)
178 {
179 RecommendationType = type;
180 PackageId = details.Id;
181 Name = details.Name;
182 PreReleaseVersion = details.PreReleaseVersion;
183 Selected = type.IsRecommendedPackage();
184 ShortDescription = details.ShortDescription;
185 Reason = reason;
186 DocsUrl = details.DocsUrl;
187 InstalledVersion = installedVersion;
188 IsInstalledAsProjectDependency = installedVersion != null && PackageManagement.IsDirectDependency(PackageId);
189 }
190
191 public RecommendedPackageViewData(PackageDetails details, RecommendedPackage recommendation, string installedVersion=null)
192 : this(details, recommendation.Type, installedVersion, recommendation.Reason)
193 {
194 }
195 }
196}