| 170 | std::map<std::string, int> error_message_history; |
| 171 | |
| 172 | ErrorResponse DisplayError(const char* title, const char* contents, ErrorType type, bool allow_repetition) { |
| 173 | display_error_mutex.lock(); |
| 174 | |
| 175 | bool no_log = false; |
| 176 | if (type == _ok_no_log) { |
| 177 | no_log = true; |
| 178 | type = _ok; |
| 179 | } |
| 180 | |
| 181 | if (!no_log) { |
| 182 | LOGI << "Displaying message: " << title << ", " << contents << std::endl; |
| 183 | LOGI << GenerateStacktrace() << std::endl; |
| 184 | } |
| 185 | |
| 186 | if (config["no_dialogues"].toBool()) { |
| 187 | display_error_mutex.unlock(); |
| 188 | return _continue; |
| 189 | } |
| 190 | |
| 191 | if (!allow_repetition && error_message_history[contents]) { |
| 192 | display_error_mutex.unlock(); |
| 193 | return _continue; |
| 194 | } |
| 195 | |
| 196 | error_message_history[contents]++; |
| 197 | |
| 198 | std::stringstream modlist; |
| 199 | |
| 200 | bool active_mods = false; |
| 201 | int active_count = 0; |
| 202 | std::vector<ModInstance*> mods = ModLoading::Instance().GetAllMods(); |
| 203 | for (auto& mod : mods) { |
| 204 | if (mod->IsActive() && mod->IsCore() == false) { |
| 205 | if (active_mods == false) { |
| 206 | modlist << "Following mods are active" << std::endl; |
| 207 | active_mods = true; |
| 208 | } else { |
| 209 | if ((active_count % 5) == 0) { |
| 210 | modlist << "," << std::endl; |
| 211 | } else { |
| 212 | modlist << ", "; |
| 213 | } |
| 214 | } |
| 215 | modlist << mod->id; |
| 216 | active_count++; |
| 217 | } |
| 218 | } |
| 219 | modlist << std::endl |
| 220 | << "Before reporting, see if disabling mods makes a difference and include this info." << std::endl; |
| 221 | |
| 222 | ErrorDisplay ed; |
| 223 | |
| 224 | ed.title = title; |
| 225 | if (active_mods) { |
| 226 | ed.pretext = modlist.str(); |
| 227 | } |
| 228 | ed.contents = contents; |
| 229 | ed.type = type; |
no test coverage detected