1 | #include "mapbugs.h" |
2 | |
3 | #include <base/system.h> |
4 | |
5 | struct CMapDescription |
6 | { |
7 | const char *m_pName; |
8 | int m_Size; |
9 | SHA256_DIGEST m_Sha256; |
10 | |
11 | bool operator==(const CMapDescription &Other) const |
12 | { |
13 | return str_comp(a: m_pName, b: Other.m_pName) == 0 && |
14 | m_Size == Other.m_Size; |
15 | } |
16 | }; |
17 | |
18 | struct CMapBugsInternal |
19 | { |
20 | CMapDescription m_Map; |
21 | unsigned int m_BugFlags; |
22 | }; |
23 | |
24 | static unsigned int BugToFlag(int Bug) |
25 | { |
26 | unsigned int Result; |
27 | dbg_assert((unsigned)Bug < 8 * sizeof(Result), "invalid shift" ); |
28 | Result = (1 << Bug); |
29 | return Result; |
30 | } |
31 | |
32 | static unsigned int IsBugFlagSet(int Bug, unsigned int BugFlags) |
33 | { |
34 | return (BugFlags & BugToFlag(Bug)) != 0; |
35 | } |
36 | |
37 | static SHA256_DIGEST s(const char *pSha256) |
38 | { |
39 | SHA256_DIGEST Result; |
40 | dbg_assert(sha256_from_str(&Result, pSha256) == 0, "invalid sha256 in mapbugs" ); |
41 | return Result; |
42 | } |
43 | |
44 | static CMapBugsInternal MAP_BUGS[] = |
45 | { |
46 | {.m_Map: {.m_pName: "Binary" , .m_Size: 2022597, .m_Sha256: s(pSha256: "65b410e197fd2298ec270e89a84b762f6739d1d18089529f8ef6cf2104d3d600" )}, .m_BugFlags: BugToFlag(Bug: BUG_GRENADE_DOUBLEEXPLOSION)}}; |
47 | |
48 | CMapBugs GetMapBugs(const char *pName, int Size, SHA256_DIGEST Sha256) |
49 | { |
50 | CMapDescription Map = {.m_pName: pName, .m_Size: Size, .m_Sha256: Sha256}; |
51 | CMapBugs Result; |
52 | Result.m_Extra = 0; |
53 | for(auto &MapBug : MAP_BUGS) |
54 | { |
55 | if(Map == MapBug.m_Map) |
56 | { |
57 | Result.m_pData = &MapBug; |
58 | return Result; |
59 | } |
60 | } |
61 | Result.m_pData = 0; |
62 | return Result; |
63 | } |
64 | |
65 | bool CMapBugs::Contains(int Bug) const |
66 | { |
67 | CMapBugsInternal *pInternal = (CMapBugsInternal *)m_pData; |
68 | if(!pInternal) |
69 | { |
70 | return IsBugFlagSet(Bug, BugFlags: m_Extra); |
71 | } |
72 | return IsBugFlagSet(Bug, BugFlags: pInternal->m_BugFlags); |
73 | } |
74 | |
75 | int CMapBugs::Update(const char *pBug) |
76 | { |
77 | CMapBugsInternal *pInternal = (CMapBugsInternal *)m_pData; |
78 | int Bug = -1; |
79 | if(false) {} |
80 | #define MAPBUG(constname, string) \ |
81 | else if(str_comp(pBug, string) == 0) { Bug = (constname); } |
82 | #include "mapbugs_list.h" |
83 | #undef MAPBUG |
84 | if(Bug == -1) |
85 | { |
86 | return MAPBUGUPDATE_NOTFOUND; |
87 | } |
88 | if(pInternal) |
89 | { |
90 | return MAPBUGUPDATE_OVERRIDDEN; |
91 | } |
92 | m_Extra |= BugToFlag(Bug); |
93 | return MAPBUGUPDATE_OK; |
94 | } |
95 | |
96 | void CMapBugs::Dump() const |
97 | { |
98 | CMapBugsInternal *pInternal = (CMapBugsInternal *)m_pData; |
99 | unsigned int Flags; |
100 | if(pInternal) |
101 | { |
102 | Flags = pInternal->m_BugFlags; |
103 | } |
104 | else if(m_Extra) |
105 | { |
106 | Flags = m_Extra; |
107 | } |
108 | else |
109 | { |
110 | return; |
111 | } |
112 | char aBugs[NUM_BUGS + 1] = {0}; |
113 | for(int i = 0; i < NUM_BUGS; i++) |
114 | { |
115 | aBugs[i] = IsBugFlagSet(Bug: i, BugFlags: Flags) ? 'X' : 'O'; |
116 | } |
117 | |
118 | dbg_msg(sys: "mapbugs" , fmt: "enabling map compatibility mode %s" , aBugs); |
119 | if(pInternal) |
120 | { |
121 | char aSha256[SHA256_MAXSTRSIZE]; |
122 | sha256_str(digest: pInternal->m_Map.m_Sha256, str: aSha256, max_len: sizeof(aSha256)); |
123 | dbg_msg(sys: "mapbugs" , fmt: "map='%s' map_size=%d map_sha256=%s" , |
124 | pInternal->m_Map.m_pName, |
125 | pInternal->m_Map.m_Size, |
126 | aSha256); |
127 | } |
128 | } |
129 | |