<commit_before>// Mozilla Firefox User Preferences

// -----------------------------------------------------------------------------
// Startup
// -----------------------------------------------------------------------------

// Show a blank page when Firefox starts
user_pref("browser.startup.homepage", "about:blank");
user_pref("browser.startup.homepage_override.mstone", "ignore");
user_pref("browser.startup.page", 0);
user_pref("startup.homepage_welcome_url", "");
user_pref("startup.homepage_welcome_url.additional", "");
user_pref("startup.homepage_override_url", "");
user_pref("browser.rights.3.shown", true);
user_pref("browser.laterrun.enabled", false);

// Show a blank page when opening new tab
user_pref("browser.newtab.preload", false);
user_pref("browser.newtabpage.enabled", false);
user_pref("browser.newtabpage.enhanced", false);
user_pref("browser.newtabpage.introShown", true);
user_pref("browser.newtabpage.directory.source", "data:text/plain,");
user_pref("browser.newtabpage.activity-stream.enabled", false);
user_pref("browser.library.activity-stream.enabled", false);

// Disable Slow Startup notifications
user_pref("browser.slowStartup.notificationDisabled", true);
user_pref("browser.slowStartup.samples", 0);
user_pref("browser.slowStartup.maxSamples", 0);

// -----------------------------------------------------------------------------
// Localization
// -----------------------------------------------------------------------------

// Choose preferred languages for displaying pages
user_pref("intl.accept_languages", "ja, zh-tw, zh, en-us, en");

// Disable GeoIP-based search results
user_pref("browser.search.countryCode", "JP");
user_pref("browser.search.region", "JP");
user_pref("browser.search.geoip.url", "");

// Disable geographically specific results/search engines
user_pref("browser.search.geoSpecificDefaults", false);
user_pref("browser.search.geoSpecificDefaults.url", "");

// -----------------------------------------------------------------------------
// Content
// -----------------------------------------------------------------------------

// Set minimum font size
user_pref("font.minimum-size.ja", 10);
user_pref("font.minimum-size.ko", 10);
user_pref("font.minimum-size.zh-CN", 10);
user_pref("font.minimum-size.zh-HK", 10);
user_pref("font.minimum-size.zh-TW", 10);

// Disable Beacon
user_pref("beacon.enabled", false);

// Disable pings
user_pref("browser.send_pings", false);
user_pref("browser.send_pings.require_same_host", true);

// Disable face detection
user_pref("camera.control.face_detection.enabled", false);

// Disable camera image capture
user_pref("dom.imagecapture.enabled", false);

// Disable canvas capture stream
user_pref("canvas.capturestream.enabled", false);

// Disallow JavaScript to move or resize window
user_pref("dom.disable_window_move_resize", true);

// Limit events that can cause a popup
user_pref("dom.popup_allowed_events", "click dblclick");

// Decrease the maximum number of popups from a single non-click event
user_pref("dom.popup_maximum", 2);

// Disable links opening in a new window
user_pref("browser.link.open_newwindow.restriction", 0);

// Disable Notifications API
user_pref("dom.webnotifications.enabled", false);
user_pref("dom.webnotifications.serviceworker.enabled", false);

// Disable Push API
user_pref("dom.push.enabled", false);
user_pref("dom.push.connection.enabled", false);
user_pref("dom.push.serverURL", "");
user_pref("dom.push.userAgentID", "");

// Disable Geolocation
user_pref("geo.enabled", false);
user_pref("geo.wifi.uri", "");
user_pref("geo.wifi.logging.enabled", false);

// Disable audio auto-play in non-active tabs
user_pref("media.block-autoplay-until-in-foreground", true);

// Disable WebRTC
user_pref("media.peerconnection.enabled", false);
user_pref("media.peerconnection.ice.tcp", false);
user_pref("media.peerconnection.identity.enabled", false);
user_pref("media.peerconnection.identity.timeout", 1);
user_pref("media.peerconnection.turn.disable", true);
user_pref("media.peerconnection.use_document_iceservers", false);
user_pref("media.peerconnection.video.enabled", false);
user_pref("media.navigator.enabled", false);
user_pref("media.navigator.video.enabled", false);

// Limit WebRTC IP leaks
user_pref("media.peerconnection.ice.default_address_only", true);
user_pref("media.peerconnection.ice.no_host", true);

// Disable WebRTC screen sharing
user_pref("media.getusermedia.screensharing.enabled", false);
user_pref("media.getusermedia.screensharing.allowed_domains", "");
user_pref("media.getusermedia.audiocapture.enabled", false);
user_pref("media.getusermedia.browser.enabled", false);

// Disable WebGL
user_pref("webgl.disabled", true);
user_pref("webgl.disable-extensions", true);
user_pref("webgl.disable-fail-if-major-performance-caveat", true);
user_pref("webgl.enable-debug-renderer-info", false);
user_pref("webgl.enable-webgl2", false);
user_pref("webgl.min_capability_mode", true);
user_pref("webgl.dxgl.enabled", false);
user_pref("pdfjs.enableWebGL", false);

// -----------------------------------------------------------------------------
// Privacy
// -----------------------------------------------------------------------------

// Enable DNT HTTP header
user_pref("privacy.donottrackheader.enabled", true);

// Enable Tracking Protection
user_pref("privacy.trackingprotection.enabled", true);
user_pref("privacy.trackingprotection.pbmode.enabled", true);
user_pref("privacy.trackingprotection.ui.enabled", true);
user_pref("privacy.trackingprotection.introCount", 20);

// Never accept third-party cookies
user_pref("network.cookie.cookieBehavior", 1);

// Disable prefetching
user_pref("network.prefetch-next", false);
user_pref("network.dns.disablePrefetch", true);
user_pref("network.dns.disablePrefetchFromHTTPS", true);
user_pref("network.predictor.enable-prefetch", false);

// Disable opening connection to links when mouseover
user_pref("network.http.speculative-parallel-limit", 0);

// Disable Seer/Necko
user_pref("network.predictor.enabled", false);
user_pref("network.captive-portal-service.enabled", false);
user_pref("captivedetect.canonicalURL", "");

// -----------------------------------------------------------------------------
// Security
// -----------------------------------------------------------------------------

// Enable Safe Browsing
user_pref("browser.safebrowsing.phishing.enabled", true);
user_pref("browser.safebrowsing.malware.enabled", true);

// Disable saving passwords
user_pref("signon.rememberSignons", false);

// Enable OCSP stapling
user_pref("security.ssl.enable_ocsp_stapling", true);
user_pref("security.OCSP.enabled", 1);
user_pref("security.OCSP.require", true);

// -----------------------------------------------------------------------------
// Features and Components
// -----------------------------------------------------------------------------

// Disable Health Report
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("datareporting.healthreport.about.reportUrl", "data:text/plain,");
user_pref("datareporting.policy.dataSubmissionEnabled", false);

// Disable Crash Reporter
user_pref("breakpad.reportURL", "");
user_pref("browser.tabs.crashReporting.sendReport", false);
user_pref("browser.crashReports.unsubmittedCheck.enabled", false);
user_pref("browser.crashReports.unsubmittedCheck.autoSubmit", false);

// Disable Telemetry
user_pref("toolkit.telemetry.enabled", false);
user_pref("toolkit.telemetry.unified", false);
user_pref("toolkit.telemetry.archive.enabled", false);
user_pref("toolkit.telemetry.cachedClientID", "");
user_pref("toolkit.telemetry.server", "");
user_pref("toolkit.telemetry.newProfilePing.enabled", false);
user_pref("toolkit.telemetry.shutdownPingSender.enabled", false);
user_pref("toolkit.telemetry.updatePing.enabled", false);
user_pref("toolkit.telemetry.bhrPing.enabled", false);
user_pref("toolkit.telemetry.firstShutdownPing.enabled", false);

// Disable Telemetry Experiments
user_pref("experiments.enabled", false);
user_pref("experiments.supported", false);
user_pref("experiments.activeExperiment", false);
user_pref("experiments.manifest.uri", "");
user_pref("network.allow-experiments", false);

// Disable Onboarding
user_pref("browser.onboarding.enabled", false);

// Disable Ping-centre telemetry
user_pref("browser.ping-centre.telemetry", false);

// Disable UITour backend
user_pref("browser.uitour.enabled", false);
user_pref("browser.uitour.url", "");

// Disable remote debugging
user_pref("devtools.webide.enabled", false);
user_pref("devtools.webide.autoinstallADBHelper", false);
user_pref("devtools.debugger.force-local", true);
user_pref("devtools.debugger.remote-enabled", false);
user_pref("devtools.chrome.enabled", false);

// Disable FlyWeb
user_pref("dom.flyweb.enabled", false);

// Disable Reader View
user_pref("reader.parse-on-load.enabled", false);

// -----------------------------------------------------------------------------
// Add-ons and Plugins
// -----------------------------------------------------------------------------

// Disable extension metadata updating
user_pref("extensions.getAddons.cache.enabled", false);

// Disable Personas (themes) updating
user_pref("lightweightThemes.update.enabled", false);

// Disable "Get Add-ons" pane
user_pref("extensions.getAddons.showPane", false);
user_pref("extensions.webservice.discoverURL", "");

// Lock down allowed extension directories
user_pref("extensions.enabledScopes", 1);

// Clear localStorage and UUID when an extension is uninstalled
user_pref("extensions.webextensions.keepStorageOnUninstall", false);
user_pref("extensions.webextensions.keepUuidOnUninstall", false);

// Disable Form Autofill
user_pref("extensions.formautofill.available", "off");
user_pref("extensions.formautofill.addresses.enabled", false);
user_pref("extensions.formautofill.creditCards.enabled", false);
user_pref("extensions.formautofill.heuristics.enabled", false);

// Disable Pocket
user_pref("extensions.pocket.enabled", false);

// Disable Shield
user_pref("extensions.shield-recipe-client.enabled", false);
user_pref("extensions.shield-recipe-client.api_url", "");

// Disable Web Compatibility Reporter
user_pref("extensions.webcompat-reporter.enabled", false);

// Disable all plugins by default
user_pref("plugin.default.state", 0);
user_pref("plugin.defaultXpi.state", 0);

// Enable click-to-play and set the session permission
user_pref("plugins.click_to_play", true);
user_pref("plugin.sessionPermissionNow.intervalInMinutes", 0);

// Disable scanning plugins on Windows
user_pref("plugin.scan.plid.all", false);

// Disable all GMP (Gecko Media Plugins)
user_pref("media.gmp-provider.enabled", false);
user_pref("media.gmp-manager.url", "data:text/plain,");
user_pref("media.gmp-manager.url.override", "data:text/plain,");
user_pref("media.gmp-manager.updateEnabled", false);
user_pref("media.gmp.trial-create.enabled", false);

// Disable widevine CDM
user_pref("media.gmp-widevinecdm.visible", false);
user_pref("media.gmp-widevinecdm.enabled", false);
user_pref("media.gmp-widevinecdm.autoupdate", false);

// Disable all DRM content
user_pref("media.eme.enabled", false);
user_pref("browser.eme.ui.enabled", false);

// Disable OpenH264 Video Codec by Cisco
user_pref("media.gmp-gmpopenh264.enabled", false);
user_pref("media.gmp-gmpopenh264.autoupdate", false);

// Skip the installation delay
user_pref("security.dialog_enable_delay", 0);

// -----------------------------------------------------------------------------
// Others
// -----------------------------------------------------------------------------

// Always ask me where to save download files
user_pref("browser.download.useDownloadDir", false);

// Disable downloading on desktop
user_pref("browser.download.folderList", 2);

// Always display download button on toolbar
user_pref("browser.download.autohideButton", false);

// Disable URL bar domain guessing
user_pref("browser.fixup.alternate.enabled", false);

// Strip password from URL
user_pref("browser.fixup.hide_user_pass", true);

// Disable capturing page thumbnails
user_pref("browser.pagethumbnails.capturing_disabled", false);

// Display search bar by default
user_pref("browser.search.widget.inNavBar", true);

// Disable closing browser with last tab
user_pref("browser.tabs.closeWindowWithLastTab", false);

// Disable Windows Taskbar Jump List
user_pref("browser.taskbar.lists.frequent.enabled", false);
user_pref("browser.taskbar.lists.recent.enabled", false);

// Disable URL bar autofill
user_pref("browser.urlbar.autoFill", false);
user_pref("browser.urlbar.autoFill.typed", false);

// Disable search suggestions in the URL bar
user_pref("browser.urlbar.suggest.searches", false);
user_pref("browser.urlbar.userMadeSearchSuggestionsChoice", true);
user_pref("browser.urlbar.oneOffSearches", false);

// Disable URL bar making speculative connections
user_pref("browser.urlbar.speculativeConnect.enabled", false);

// Display all parts of the URL in the URL bar
user_pref("browser.urlbar.trimURLs", false);

// Disable preloading top websites in the URL bar
user_pref("browser.urlbar.usepreloadedtopurls.enabled", false);

// Disable site specific zoom
user_pref("browser.zoom.siteSpecific", false);

// Disable `about:config` warnings
user_pref("general.warnOnAboutConfig", false);

// Display the raw Punycode in the URL bar
user_pref("network.IDN_show_punycode", true);

// Disable links launching Windows Store
user_pref("network.protocol-handler.external.ms-windows-store", false);

// Disable Windows Family Safety Mode
user_pref("security.family_safety.mode", 0);

// Disable UI animation
user_pref("toolkit.cosmeticAnimations.enabled", false);
user_pref("browser.stopReloadAnimation.enabled", false);

// Prevent accessibility services from accessing your browser
user_pref("accessibility.force_disabled", 1);
<commit_msg>Sort preferences by name in user.js<commit_after>// Mozilla Firefox User Preferences

// -----------------------------------------------------------------------------
// Startup
// -----------------------------------------------------------------------------

// Show a blank page when Firefox starts
user_pref("browser.startup.homepage", "about:blank");
user_pref("browser.startup.homepage_override.mstone", "ignore");
user_pref("browser.startup.page", 0);
user_pref("startup.homepage_welcome_url", "");
user_pref("startup.homepage_welcome_url.additional", "");
user_pref("startup.homepage_override_url", "");
user_pref("browser.rights.3.shown", true);
user_pref("browser.laterrun.enabled", false);

// Show a blank page when opening new tab
user_pref("browser.newtab.preload", false);
user_pref("browser.newtabpage.enabled", false);
user_pref("browser.newtabpage.enhanced", false);
user_pref("browser.newtabpage.introShown", true);
user_pref("browser.newtabpage.directory.source", "data:text/plain,");
user_pref("browser.newtabpage.activity-stream.enabled", false);
user_pref("browser.library.activity-stream.enabled", false);

// Disable Slow Startup notifications
user_pref("browser.slowStartup.notificationDisabled", true);
user_pref("browser.slowStartup.samples", 0);
user_pref("browser.slowStartup.maxSamples", 0);

// -----------------------------------------------------------------------------
// Localization
// -----------------------------------------------------------------------------

// Choose preferred languages for displaying pages
user_pref("intl.accept_languages", "ja, zh-tw, zh, en-us, en");

// Disable GeoIP-based search results
user_pref("browser.search.countryCode", "JP");
user_pref("browser.search.region", "JP");
user_pref("browser.search.geoip.url", "");

// Disable geographically specific results/search engines
user_pref("browser.search.geoSpecificDefaults", false);
user_pref("browser.search.geoSpecificDefaults.url", "");

// -----------------------------------------------------------------------------
// Content
// -----------------------------------------------------------------------------

// Set minimum font size
user_pref("font.minimum-size.ja", 10);
user_pref("font.minimum-size.ko", 10);
user_pref("font.minimum-size.zh-CN", 10);
user_pref("font.minimum-size.zh-HK", 10);
user_pref("font.minimum-size.zh-TW", 10);

// Disable Beacon
user_pref("beacon.enabled", false);

// Disable pings
user_pref("browser.send_pings", false);
user_pref("browser.send_pings.require_same_host", true);

// Disable face detection
user_pref("camera.control.face_detection.enabled", false);

// Disable camera image capture
user_pref("dom.imagecapture.enabled", false);

// Disable canvas capture stream
user_pref("canvas.capturestream.enabled", false);

// Disallow JavaScript to move or resize window
user_pref("dom.disable_window_move_resize", true);

// Limit events that can cause a popup
user_pref("dom.popup_allowed_events", "click dblclick");

// Decrease the maximum number of popups from a single non-click event
user_pref("dom.popup_maximum", 2);

// Disable links opening in a new window
user_pref("browser.link.open_newwindow.restriction", 0);

// Disable Notifications API
user_pref("dom.webnotifications.enabled", false);
user_pref("dom.webnotifications.serviceworker.enabled", false);

// Disable Push API
user_pref("dom.push.enabled", false);
user_pref("dom.push.connection.enabled", false);
user_pref("dom.push.serverURL", "");
user_pref("dom.push.userAgentID", "");

// Disable Geolocation
user_pref("geo.enabled", false);
user_pref("geo.wifi.uri", "");
user_pref("geo.wifi.logging.enabled", false);

// Disable audio auto-play in non-active tabs
user_pref("media.block-autoplay-until-in-foreground", true);

// Disable WebRTC
user_pref("media.peerconnection.enabled", false);
user_pref("media.peerconnection.ice.tcp", false);
user_pref("media.peerconnection.identity.enabled", false);
user_pref("media.peerconnection.identity.timeout", 1);
user_pref("media.peerconnection.turn.disable", true);
user_pref("media.peerconnection.use_document_iceservers", false);
user_pref("media.peerconnection.video.enabled", false);
user_pref("media.navigator.enabled", false);
user_pref("media.navigator.video.enabled", false);

// Limit WebRTC IP leaks
user_pref("media.peerconnection.ice.default_address_only", true);
user_pref("media.peerconnection.ice.no_host", true);

// Disable WebRTC screen sharing
user_pref("media.getusermedia.screensharing.enabled", false);
user_pref("media.getusermedia.screensharing.allowed_domains", "");
user_pref("media.getusermedia.audiocapture.enabled", false);
user_pref("media.getusermedia.browser.enabled", false);

// Disable WebGL
user_pref("webgl.disabled", true);
user_pref("webgl.disable-extensions", true);
user_pref("webgl.disable-fail-if-major-performance-caveat", true);
user_pref("webgl.enable-debug-renderer-info", false);
user_pref("webgl.enable-webgl2", false);
user_pref("webgl.min_capability_mode", true);
user_pref("webgl.dxgl.enabled", false);
user_pref("pdfjs.enableWebGL", false);

// -----------------------------------------------------------------------------
// Privacy
// -----------------------------------------------------------------------------

// Enable DNT HTTP header
user_pref("privacy.donottrackheader.enabled", true);

// Enable Tracking Protection
user_pref("privacy.trackingprotection.enabled", true);
user_pref("privacy.trackingprotection.pbmode.enabled", true);
user_pref("privacy.trackingprotection.ui.enabled", true);
user_pref("privacy.trackingprotection.introCount", 20);

// Never accept third-party cookies
user_pref("network.cookie.cookieBehavior", 1);

// Disable prefetching
user_pref("network.prefetch-next", false);
user_pref("network.dns.disablePrefetch", true);
user_pref("network.dns.disablePrefetchFromHTTPS", true);
user_pref("network.predictor.enable-prefetch", false);

// Disable opening connection to links when mouseover
user_pref("network.http.speculative-parallel-limit", 0);

// Disable Seer/Necko
user_pref("network.predictor.enabled", false);
user_pref("network.captive-portal-service.enabled", false);
user_pref("captivedetect.canonicalURL", "");

// -----------------------------------------------------------------------------
// Security
// -----------------------------------------------------------------------------

// Enable Safe Browsing
user_pref("browser.safebrowsing.phishing.enabled", true);
user_pref("browser.safebrowsing.malware.enabled", true);

// Disable saving passwords
user_pref("signon.rememberSignons", false);

// Enable OCSP stapling
user_pref("security.ssl.enable_ocsp_stapling", true);
user_pref("security.OCSP.enabled", 1);
user_pref("security.OCSP.require", true);

// -----------------------------------------------------------------------------
// Features and Components
// -----------------------------------------------------------------------------

// Disable Health Report
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("datareporting.healthreport.about.reportUrl", "data:text/plain,");
user_pref("datareporting.policy.dataSubmissionEnabled", false);

// Disable Crash Reporter
user_pref("breakpad.reportURL", "");
user_pref("browser.tabs.crashReporting.sendReport", false);
user_pref("browser.crashReports.unsubmittedCheck.enabled", false);
user_pref("browser.crashReports.unsubmittedCheck.autoSubmit", false);

// Disable Telemetry
user_pref("toolkit.telemetry.enabled", false);
user_pref("toolkit.telemetry.unified", false);
user_pref("toolkit.telemetry.archive.enabled", false);
user_pref("toolkit.telemetry.cachedClientID", "");
user_pref("toolkit.telemetry.server", "");
user_pref("toolkit.telemetry.newProfilePing.enabled", false);
user_pref("toolkit.telemetry.shutdownPingSender.enabled", false);
user_pref("toolkit.telemetry.updatePing.enabled", false);
user_pref("toolkit.telemetry.bhrPing.enabled", false);
user_pref("toolkit.telemetry.firstShutdownPing.enabled", false);

// Disable Telemetry Experiments
user_pref("experiments.enabled", false);
user_pref("experiments.supported", false);
user_pref("experiments.activeExperiment", false);
user_pref("experiments.manifest.uri", "");
user_pref("network.allow-experiments", false);

// Disable Onboarding
user_pref("browser.onboarding.enabled", false);

// Disable Ping-centre telemetry
user_pref("browser.ping-centre.telemetry", false);

// Disable UITour backend
user_pref("browser.uitour.enabled", false);
user_pref("browser.uitour.url", "");

// Disable remote debugging
user_pref("devtools.webide.enabled", false);
user_pref("devtools.webide.autoinstallADBHelper", false);
user_pref("devtools.debugger.force-local", true);
user_pref("devtools.debugger.remote-enabled", false);
user_pref("devtools.chrome.enabled", false);

// Disable FlyWeb
user_pref("dom.flyweb.enabled", false);

// Disable Reader View
user_pref("reader.parse-on-load.enabled", false);

// -----------------------------------------------------------------------------
// Add-ons and Plugins
// -----------------------------------------------------------------------------

// Disable extension metadata updating
user_pref("extensions.getAddons.cache.enabled", false);

// Disable Personas (themes) updating
user_pref("lightweightThemes.update.enabled", false);

// Disable "Get Add-ons" pane
user_pref("extensions.getAddons.showPane", false);
user_pref("extensions.webservice.discoverURL", "");

// Lock down allowed extension directories
user_pref("extensions.enabledScopes", 1);

// Clear localStorage and UUID when an extension is uninstalled
user_pref("extensions.webextensions.keepStorageOnUninstall", false);
user_pref("extensions.webextensions.keepUuidOnUninstall", false);

// Disable Form Autofill
user_pref("extensions.formautofill.available", "off");
user_pref("extensions.formautofill.addresses.enabled", false);
user_pref("extensions.formautofill.creditCards.enabled", false);
user_pref("extensions.formautofill.heuristics.enabled", false);

// Disable Pocket
user_pref("extensions.pocket.enabled", false);

// Disable Shield
user_pref("extensions.shield-recipe-client.enabled", false);
user_pref("extensions.shield-recipe-client.api_url", "");

// Disable Web Compatibility Reporter
user_pref("extensions.webcompat-reporter.enabled", false);

// Disable all plugins by default
user_pref("plugin.default.state", 0);
user_pref("plugin.defaultXpi.state", 0);

// Enable click-to-play and set the session permission
user_pref("plugins.click_to_play", true);
user_pref("plugin.sessionPermissionNow.intervalInMinutes", 0);

// Disable scanning plugins on Windows
user_pref("plugin.scan.plid.all", false);

// Disable all GMP (Gecko Media Plugins)
user_pref("media.gmp-provider.enabled", false);
user_pref("media.gmp-manager.url", "data:text/plain,");
user_pref("media.gmp-manager.url.override", "data:text/plain,");
user_pref("media.gmp-manager.updateEnabled", false);
user_pref("media.gmp.trial-create.enabled", false);

// Disable widevine CDM
user_pref("media.gmp-widevinecdm.visible", false);
user_pref("media.gmp-widevinecdm.enabled", false);
user_pref("media.gmp-widevinecdm.autoupdate", false);

// Disable all DRM content
user_pref("media.eme.enabled", false);
user_pref("browser.eme.ui.enabled", false);

// Disable OpenH264 Video Codec by Cisco
user_pref("media.gmp-gmpopenh264.enabled", false);
user_pref("media.gmp-gmpopenh264.autoupdate", false);

// Skip the installation delay
user_pref("security.dialog_enable_delay", 0);

// -----------------------------------------------------------------------------
// Others
// -----------------------------------------------------------------------------

// Prevent accessibility services from accessing browser
user_pref("accessibility.force_disabled", 1);

// Always ask me where to save download files
user_pref("browser.download.useDownloadDir", false);

// Disable downloading on desktop
user_pref("browser.download.folderList", 2);

// Always display download button on toolbar
user_pref("browser.download.autohideButton", false);

// Disable URL bar domain guessing
user_pref("browser.fixup.alternate.enabled", false);

// Strip password from URL
user_pref("browser.fixup.hide_user_pass", true);

// Disable capturing page thumbnails
user_pref("browser.pagethumbnails.capturing_disabled", false);

// Display search bar by default
user_pref("browser.search.widget.inNavBar", true);

// Disable closing browser with last tab
user_pref("browser.tabs.closeWindowWithLastTab", false);

// Disable Windows Taskbar Jump List
user_pref("browser.taskbar.lists.frequent.enabled", false);
user_pref("browser.taskbar.lists.recent.enabled", false);

// Disable URL bar autofill
user_pref("browser.urlbar.autoFill", false);
user_pref("browser.urlbar.autoFill.typed", false);

// Disable search suggestions in the URL bar
user_pref("browser.urlbar.suggest.searches", false);
user_pref("browser.urlbar.userMadeSearchSuggestionsChoice", true);
user_pref("browser.urlbar.oneOffSearches", false);

// Disable URL bar making speculative connections
user_pref("browser.urlbar.speculativeConnect.enabled", false);

// Display all parts of the URL in the URL bar
user_pref("browser.urlbar.trimURLs", false);

// Disable preloading top websites in the URL bar
user_pref("browser.urlbar.usepreloadedtopurls.enabled", false);

// Disable site specific zoom
user_pref("browser.zoom.siteSpecific", false);

// Disable `about:config` warnings
user_pref("general.warnOnAboutConfig", false);

// Display the raw Punycode in the URL bar
user_pref("network.IDN_show_punycode", true);

// Disable links launching Windows Store
user_pref("network.protocol-handler.external.ms-windows-store", false);

// Disable Windows Family Safety Mode
user_pref("security.family_safety.mode", 0);

// Disable UI animation
user_pref("toolkit.cosmeticAnimations.enabled", false);
user_pref("browser.stopReloadAnimation.enabled", false);
<|endoftext|>


<commit_before>// images for game pieces

const xImage = "http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/black-ink-grunge-stamps-textures-icons-alphanumeric/068726-black-ink-grunge-stamp-textures-icon-alphanumeric-x-solid.png"
const oImage ="http://www.drodd.com/images14/o25.png"
const emptySquare = "http://1.bp.blogspot.com/-jJUO43k6ReU/T7ivfcr4fgI/AAAAAAAAQqU/8YdJwPwT4OE/s1600/transparent.png"

//role for local player
var playerRole;

//local reference for firebase data
let whoseTurn;
let gameover;
var plays;
var users;

//hide the playagain button

const maxMsg = 10

const form = document.querySelector('form')
const messagesRef = firebase.database().ref('messages')
const messagesDiv = document.querySelector('.messages')

$(".playAgain").hide()
$(".exit-game").hide()

//--------- PAGE LOAD -----------------
//on pageload, reset firebase array
firebase.database().ref("moves").set(["Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"]);
//current player is x
firebase.database()
  .ref("currentPlayer").set("x");
//moves = zero
firebase.database()
  .ref("plays").set(0)

//game is not over
firebase.database()
.ref("gameover").set(false)

//------------------ FIREBASE SNAPS ------------------
//listen for change in the player on firebase on game start
firebase.database()
  .ref("currentPlayer")
  .once("value")
  .then(snap => snap.val())
  .then((value)=>{
    whoseTurn = value;
  })
  //listens for set of gameover value at start
  firebase.database()
  .ref("gameover")
  .once("value")
  .then(snap => snap.val())
  .then((value)=>{
    gameover = value;
    console.log("gameover", gameover)
  })

//listens for change in moves array
firebase.database()
  .ref("moves")
  .on("value", setCurrentArray)

function setCurrentArray(snap) {
  if(snap) {
    let val = snap.val()
    currentArray = val;
    //updates board to current array value
    updateBoard(val)
    console.log("currentArray", currentArray)
    //calls the check for win function

    checkForWin(val)

  }
}

//listens for change in player in
firebase.database()
  .ref("currentPlayer")
  .on("value", setWhoseTurn)

  function setWhoseTurn(snap) {
    if(snap) {
      let val = snap.val()
      whoseTurn = val;
      console.log("whoseTurn", whoseTurn)
    }
  }

//listens for change in gameover
firebase.database()
  .ref("gameover")
  .on("value", setGameOver)

  function setGameOver(snap) {
    if(snap) {
      let val = snap.val()
      gameover = val;
      console.log("gameover", gameover)
      // if(gameover === true) {
      //   $(".playAgain").show()
      //   $(".exit-game").show()
      // } else {
      //   $(".playAgain").hide()
      //   $(".exit-game").hide()
      // }
    }
  }
//listens for change in play count

firebase.database()
  .ref("plays")
  .on("value", setPlay)

function setPlay(snap){
    if(snap) {
      let val = snap.val()
      plays = val;
      console.log("plays", plays)

    }
}

//listens for change in user count

firebase.database()
  .ref("users")
  .on("value", setUser)

  firebase.database()
  .ref("users")
  .once("value", assignRole)

function setUser(snap){
    if(snap) {
      let val = snap.val()
      users = val;
      console.log("users", users)

    }
}

function assignRole(snap) {
    if(snap) {
      let val = snap.val()
      users = val;
      if (users === null || users === 0) {
        playerRole = "x"
      } else if (users === 1){
        playerRole = "o"
      }
      $(".playerCard").html(`<h4>You're Player ${playerRole}</h4>`)
      console.log("playerRole", playerRole)
    }
}

//event listeners on DOM
$("td").click(changeSquare) //calls function to change image

$(".playAgain").click(playAgain)

function changeSquare(evt) {
  console.log("I've been clicked")

  //resets the image of the clicked on square to new value
   let clickedSquare = evt.target
   //captures data position of clicked target
   let squarePosition = parseInt(evt.target.closest('td').dataset.position);

   //if valid array, update firebase
   if(clickedSquare.src === emptySquare && gameover !== true && whoseTurn === playerRole) {
    //adds data position to array that stores the players choices
   firebase.database().ref("moves").update({ [squarePosition] : whoseTurn})
   //add play to count of plays
   let newPlayCount = (plays + 1)
   firebase.database().ref("plays").set(newPlayCount)

   //run the check for win function

  }
 }

// ------------------------ Check For Win ----------------------------

// firebase.database().ref("moves").on('value', checkForWin)

function checkForWin(snap) {
  let a = snap
  var wc = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6],[1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ];

  for(var i = 0; i < wc.length; i++) {

    if(a[wc[i][0]] !== "Z") {
      if ((a[wc[i][0]] === a[wc[i][1]]) && (a[wc[i][1]] === a[wc[i][2]])) {
        console.log("you win!!!")
        announceGameEnd("win")
        return
      }
    }
  }

  console.log("plays", plays);
  if (plays === 8) {
    console.log("tie");
    announceGameEnd();
    return
  }

  if(a !== ["Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"]){
     changePlayers();
  }

}

 //on the change player function
function updateBoard(array) {
  console.log("array", array)
  //for each value in the array
  for(var i = 0; i < array.length; i++) {
      //assign the array's value at that position to a var
    let arrayValue = array[i];
    let whichSquare = i;
    //if that value is an x
    if(arrayValue === "x") {
    //write the x image to the html img tag
      let imageSquare = `<img src=${xImage} width="150" height="150">`
     //update that square with the player's x image
      $(`td[data-position=${whichSquare}]`).html(imageSquare)
    //if that player is an oimage
    } else if(arrayValue === "o") {
      //write that  oimage to the html img tag
      let imageSquare = `<img src=${oImage} width="150" height="150">`
     //update that square with the player's  o image
      $(`td[data-position=${whichSquare}]`).html(imageSquare)
    }
    else {
      //write that   clear image to the html img tag
      let imageSquare = `<img src=${emptySquare} width="150" height="150">`
     //update that square with the player's  o image
      $(`td[data-position=${whichSquare}]`).html(imageSquare)
    }
  }

}

function changePlayers() {
   if (whoseTurn === "x") {
    //if it's x, change to o
    firebase.database().ref("currentPlayer").set("o");
    //change the play marker
    $(".playerMarker").html("
It is O's turn
")
   } else {
    //else if it's o, change to x
    firebase.database().ref("currentPlayer").set("x");
    //change the play marker
    $(".playerMarker").html("
It is X's turn
")
   }
}

function changeBanner() {
  if (whoseTurn === "x") {
    //if it's x, change to o
    //change the play marker
    $(".playerMarker").html("
It is O's turn
")
   } else {
    //else if it's o, change to x
    //change the play marker
    $(".playerMarker").html("
It is X's turn
")
   }
}

function announceGameEnd(message) {
  //set the gameover value to true

  firebase.database().ref("gameover").set(true)
  //if the current player = x, x is winner, else o is winner
  let winner = (whoseTurn === "x") ? "X" : "O"
  let announcement = `<h1>${winner} won!</h1>`
  if (message === "win") {
    //announce winner
    $(".playerMarker h1").html(announcement)
    //show play again button
    $(".playAgain").show()
    $(".exit-game").show()
  } else {
    $(".playerMarker").html("
It's a draw!
")
    $(".playAgain").show()
    $(".exit-game").show()

  }

}

function playAgain() {
  //resets firebase

  // reset firebase array
  firebase.database().ref("moves").set(["Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"]);
  //current player is x
  firebase.database()
    .ref("currentPlayer").set("x");
  //moves = zero
  firebase.database()
    .ref("plays").set(0)

  //game is not over
  firebase.database()
    .ref("gameover").set(false)

    $(".playAgain").hide()
    $(".exit-game").hide()

  //make sure current first player is x,
  if(whoseTurn !== "x") {
    changePlayers()
  }

}

$('.enter-game').click(()=>{

    $('.landing').addClass('hide');
    $('.game_container').removeClass('hide');
    $('.messages').empty()
    //signs user in
    joinGame();

})

$('.exit-game').click(()=>{

  $('.game_container').addClass('hide');
  $('.landing').removeClass('hide');
  //take user out of playing position
  // reset firebase array
  firebase.database().ref("moves").set(["Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"]);
  //current player is x
  firebase.database()
    .ref("currentPlayer").set("x");
  //moves = zero
  firebase.database()
    .ref("plays").set(0)

  //game is not over
  firebase.database()
    .ref("gameover").set(false)

  $('.messages').empty()

  //signs user out
  leaveGame()

})

const sendMessage = (evt) => {
  evt.preventDefault()

  const nameInput = evt.target.elements.name // evt.target.querySelctor('[name="name"]')
  const contentInput = evt.target.elements.content // evt.target.querySelctor('[name="content"]')

  const name = nameInput.value.trim()
  const content = contentInput.value.trim()

  if (name && content) {
    messagesRef.push({ name, content })
      .then(() => contentInput.value = '')
  }
}

const renderMessage = (msg) => {
   const docFragment = document.createDocumentFragment()

   const div = document.createElement('DIV')
   docFragment.appendChild(div)

   const strong = document.createElement('STRONG')
   div.appendChild(strong)

   const name = document.createTextNode(msg.name)
   strong.appendChild(name)

   const seperator = document.createTextNode(': ')
   div.appendChild(seperator)

   const span = document.createElement('SPAN')
   div.appendChild(span)

   const content = document.createTextNode(msg.content)
   span.appendChild(content)

   return docFragment
 }

 const onNewMessage = (snap) => {
   const msg = snap.val() // { name: 'Scott', content: 'Hey' }

   messagesDiv.appendChild(renderMessage(msg))

   // messagesDiv.innerHTML += `
   //

   //     ${msg.name}: ${msg.content}
   //

   // `

   if (messagesDiv.childElementCount > maxMsg) {
     messagesDiv.firstChild.remove()
   }
 }

 form.addEventListener('submit', sendMessage)

 messagesRef.limitToLast(maxMsg).on('child_added', onNewMessage)

//User Auth

function joinGame() {
  firebase.auth()
    .signInAnonymously()
    .then((e)=>{
      console.log("e.uid", e.uid)
      //set user count to one
      let updateUser = users ? users+= 1 : 1;
      firebase.database()
        .ref("users")
        .set(updateUser);
      //call function to assign user role
    })
    .catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  console.log("error", errorMessage)
  })
}

function leaveGame() {
  firebase.auth()
    .signOut()
    .then(()=>{
      let updateUser = users-= 1;
      firebase.database()
        .ref("users")
        .set(users);
    })
}

firebase.auth().signInAnonymously().catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  // ...
});

 firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
    var isAnonymous = user.isAnonymous;
    var uid = user.uid;
    // ...
  } else {
    // User is signed out.
    // ...
  }
  // ...
});
<commit_msg>broken user count<commit_after>// images for game pieces

const xImage = "http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/black-ink-grunge-stamps-textures-icons-alphanumeric/068726-black-ink-grunge-stamp-textures-icon-alphanumeric-x-solid.png"
const oImage ="http://www.drodd.com/images14/o25.png"
const emptySquare = "http://1.bp.blogspot.com/-jJUO43k6ReU/T7ivfcr4fgI/AAAAAAAAQqU/8YdJwPwT4OE/s1600/transparent.png"

//role for local player
var playerRole;

//local reference for firebase data
let whoseTurn;
let gameover;
var plays;
var users;

//hide the playagain button

const maxMsg = 10

const form = document.querySelector('form')
const messagesRef = firebase.database().ref('messages')
const messagesDiv = document.querySelector('.messages')

// firebase.auth()
//   .onAuthStateChanged((user)=> {
//     return user;
//   })
//   .then(user =>{
//     if(user) {
//       console.log("there is a user")
//       let updateUser = users-= 1;
//       firebase.database()
//         .ref("users")
//         .set(users);
//     }
//   })

$(".playAgain").hide()
$(".exit-game").hide()

//--------- PAGE LOAD -----------------
//on pageload, reset firebase array
firebase.database().ref("moves").set(["Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"]);
//current player is x
firebase.database()
  .ref("currentPlayer").set("x");
//moves = zero
firebase.database()
  .ref("plays").set(0)

//game is not over
firebase.database()
.ref("gameover").set(false)

//------------------ FIREBASE SNAPS ------------------
//listen for change in the player on firebase on game start
firebase.database()
  .ref("currentPlayer")
  .once("value")
  .then(snap => snap.val())
  .then((value)=>{
    whoseTurn = value;
  })
  //listens for set of gameover value at start
  firebase.database()
  .ref("gameover")
  .once("value")
  .then(snap => snap.val())
  .then((value)=>{
    gameover = value;
    console.log("gameover", gameover)
  })

//listens for change in moves array
firebase.database()
  .ref("moves")
  .on("value", setCurrentArray)

function setCurrentArray(snap) {
  if(snap) {
    let val = snap.val()
    currentArray = val;
    //updates board to current array value
    updateBoard(val)
    console.log("currentArray", currentArray)
    //calls the check for win function

    checkForWin(val)

  }
}

//listens for change in player in
firebase.database()
  .ref("currentPlayer")
  .on("value", setWhoseTurn)

  function setWhoseTurn(snap) {
    if(snap) {
      let val = snap.val()
      whoseTurn = val;
      console.log("whoseTurn", whoseTurn)
    }
  }

//listens for change in gameover
firebase.database()
  .ref("gameover")
  .on("value", setGameOver)

  function setGameOver(snap) {
    if(snap) {
      let val = snap.val()
      gameover = val;
      console.log("gameover", gameover)
      // if(gameover === true) {
      //   $(".playAgain").show()
      //   $(".exit-game").show()
      // } else {
      //   $(".playAgain").hide()
      //   $(".exit-game").hide()
      // }
    }
  }
//listens for change in play count

firebase.database()
  .ref("plays")
  .on("value", setPlay)

function setPlay(snap){
    if(snap) {
      let val = snap.val()
      plays = val;
      console.log("plays", plays)

    }
}

//listens for change in user count

firebase.database()
  .ref("users")
  .on("value", setUser)

  // firebase.database()
  // .ref("users")
  // .once("value", assignRole)

function setUser(snap){
    if(snap) {
      let val = snap.val()
      users = val;
      console.log("users", users)

    }
}

function assignRole() {
      if (users === null || users === 0) {
        playerRole = "x"
      } else if (users === 1){
        playerRole = "o"
      } else {
        playerRole = " an observer (You're just watching the game)"
      }
      $(".playerCard").html(`<h4>You're ${playerRole}</h4>`)
      console.log("playerRole", playerRole)
}

//event listeners on DOM
$("td").click(changeSquare) //calls function to change image

$(".playAgain").click(playAgain)

function changeSquare(evt) {
  console.log("I've been clicked")

  //resets the image of the clicked on square to new value
   let clickedSquare = evt.target
   //captures data position of clicked target
   let squarePosition = parseInt(evt.target.closest('td').dataset.position);

   //if valid array, update firebase
   if(clickedSquare.src === emptySquare && gameover !== true && whoseTurn === playerRole) {
    //adds data position to array that stores the players choices
   firebase.database().ref("moves").update({ [squarePosition] : whoseTurn})
   //add play to count of plays
   let newPlayCount = (plays + 1)
   firebase.database().ref("plays").set(newPlayCount)

   //run the check for win function

  }
 }

// ------------------------ Check For Win ----------------------------

// firebase.database().ref("moves").on('value', checkForWin)

function checkForWin(snap) {
  let a = snap
  var wc = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6],[1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ];

  for(var i = 0; i < wc.length; i++) {

    if(a[wc[i][0]] !== "Z") {
      if ((a[wc[i][0]] === a[wc[i][1]]) && (a[wc[i][1]] === a[wc[i][2]])) {
        console.log("you win!!!")
        announceGameEnd("win")
        return
      }
    }
  }

  console.log("plays", plays);
  if (plays === 8) {
    console.log("tie");
    announceGameEnd();
    return
  }

  if(a !== ["Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"]){
     changePlayers();
  }

}

 //on the change player function
function updateBoard(array) {
  console.log("array", array)
  //for each value in the array
  for(var i = 0; i < array.length; i++) {
      //assign the array's value at that position to a var
    let arrayValue = array[i];
    let whichSquare = i;
    //if that value is an x
    if(arrayValue === "x") {
    //write the x image to the html img tag
      let imageSquare = `<img src=${xImage} width="150" height="150">`
     //update that square with the player's x image
      $(`td[data-position=${whichSquare}]`).html(imageSquare)
    //if that player is an oimage
    } else if(arrayValue === "o") {
      //write that  oimage to the html img tag
      let imageSquare = `<img src=${oImage} width="150" height="150">`
     //update that square with the player's  o image
      $(`td[data-position=${whichSquare}]`).html(imageSquare)
    }
    else {
      //write that   clear image to the html img tag
      let imageSquare = `<img src=${emptySquare} width="150" height="150">`
     //update that square with the player's  o image
      $(`td[data-position=${whichSquare}]`).html(imageSquare)
    }
  }

}

function changePlayers() {
   if (whoseTurn === "x") {
    //if it's x, change to o
    firebase.database().ref("currentPlayer").set("o");
    //change the play marker
    $(".playerMarker").html("
It is O's turn
")
   } else {
    //else if it's o, change to x
    firebase.database().ref("currentPlayer").set("x");
    //change the play marker
    $(".playerMarker").html("
It is X's turn
")
   }
}

function changeBanner() {
  if (whoseTurn === "x") {
    //if it's x, change to o
    //change the play marker
    $(".playerMarker").html("
It is O's turn
")
   } else {
    //else if it's o, change to x
    //change the play marker
    $(".playerMarker").html("
It is X's turn
")
   }
}

function announceGameEnd(message) {
  //set the gameover value to true

  firebase.database().ref("gameover").set(true)
  //if the current player = x, x is winner, else o is winner
  let winner = (whoseTurn === "x") ? "X" : "O"
  let announcement = `<h1>${winner} won!</h1>`
  if (message === "win") {
    //announce winner
    $(".playerMarker h1").html(announcement)
    //show play again button
    $(".playAgain").show()
    $(".exit-game").show()
  } else {
    $(".playerMarker").html("
It's a draw!
")
    $(".playAgain").show()
    $(".exit-game").show()

  }

}

function playAgain() {
  //resets firebase

  // reset firebase array
  firebase.database().ref("moves").set(["Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"]);
  //current player is x
  firebase.database()
    .ref("currentPlayer").set("x");
  //moves = zero
  firebase.database()
    .ref("plays").set(0)

  //game is not over
  firebase.database()
    .ref("gameover").set(false)

    $(".playAgain").hide()
    $(".exit-game").hide()

  //make sure current first player is x,
  if(whoseTurn !== "x") {
    changePlayers()
  }

}

$('.enter-game').click(()=>{

    $('.landing').addClass('hide');
    $('.game_container').removeClass('hide');
    $('.messages').empty()
    //signs user in
    joinGame();

})

$('.exit-game').click(()=>{

  $('.game_container').addClass('hide');
  $('.landing').removeClass('hide');
  //take user out of playing position
  // reset firebase array
  firebase.database().ref("moves").set(["Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"]);
  //current player is x
  firebase.database()
    .ref("currentPlayer").set("x");
  //moves = zero
  firebase.database()
    .ref("plays").set(0)

  //game is not over
  firebase.database()
    .ref("gameover").set(false)

  $('.messages').empty()

  //signs user out
  leaveGame()

})

const sendMessage = (evt) => {
  evt.preventDefault()

  const nameInput = evt.target.elements.name // evt.target.querySelctor('[name="name"]')
  const contentInput = evt.target.elements.content // evt.target.querySelctor('[name="content"]')

  const name = nameInput.value.trim()
  const content = contentInput.value.trim()

  if (name && content) {
    messagesRef.push({ name, content })
      .then(() => contentInput.value = '')
  }
}

const renderMessage = (msg) => {
   const docFragment = document.createDocumentFragment()

   const div = document.createElement('DIV')
   docFragment.appendChild(div)

   const strong = document.createElement('STRONG')
   div.appendChild(strong)

   const name = document.createTextNode(msg.name)
   strong.appendChild(name)

   const seperator = document.createTextNode(': ')
   div.appendChild(seperator)

   const span = document.createElement('SPAN')
   div.appendChild(span)

   const content = document.createTextNode(msg.content)
   span.appendChild(content)

   return docFragment
 }

 const onNewMessage = (snap) => {
   const msg = snap.val() // { name: 'Scott', content: 'Hey' }

   messagesDiv.appendChild(renderMessage(msg))

   // messagesDiv.innerHTML += `
   //

   //     ${msg.name}: ${msg.content}
   //

   // `

   if (messagesDiv.childElementCount > maxMsg) {
     messagesDiv.firstChild.remove()
   }
 }

 form.addEventListener('submit', sendMessage)

 messagesRef.limitToLast(maxMsg).on('child_added', onNewMessage)

//User Auth

function joinGame() {
  firebase.auth()
    .signInAnonymously()
    .then((e)=>{
      console.log("e.uid", e.uid)
      assignRole();
      //set user count to one
      let updateUser = users ? users+= 1 : 1;
      firebase.database()
        .ref("users")
        .set(updateUser);
      //call function to assign user role
    })
    .catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  console.log("error", errorMessage)
  })
}

function leaveGame() {
  firebase.auth()
    .signOut()
    .then(()=>{
      let updateUser = users-= 1;
      firebase.database()
        .ref("users")
        .set(users);
    })
}

// firebase.auth().signInAnonymously().catch(function(error) {
//   // Handle Errors here.
//   var errorCode = error.code;
//   var errorMessage = error.message;
//   // ...
// });

  function checkForUser() {
    firebase.auth().onAuthStateChanged(function(user) {
      // checkForUser()
      console.log("user", user)
      if (user === null) {
        console.log("no user")
        } else if (user !== null && playerRole === undefined){
        // User is signed in.
        console.log("inside the function")
        var isAnonymous = user.isAnonymous;
        var uid = user.uid;
        let updateUser = users=- 1;
          firebase.database()
            .ref("users")
            .set(updateUser);

        firebase.auth().signOut();
      // ...
    } else {
      // User is signed out.
      // ...
    }
    // ...
  });
}

checkForUser()
<|endoftext|>


<commit_before>// @flow

import React from 'react';
import { ReactiveList } from '@appbaseio/reactivesearch';
import { connect } from 'react-redux';
import styled, { css } from 'react-emotion';
import { mediaMin } from '@divyanshu013/media';

import DataTable from '../DataTable';
import Flex from '../Flex';
import Loader from '../Loader';

import { numberWithCommas, getUrlParams } from '../../utils';
import { getSort } from '../../reducers/sort';
import { getPageSize } from '../../reducers/pageSize';
import { getAppname } from '../../reducers/app';
import { getReactiveListKey } from '../../reducers/data';
import { getVersion } from '../../reducers/version';
import {
	getTermsAggregationColumns,
	getMappings,
} from '../../reducers/mappings';
import {
	setSelectedRows,
	setUpdatingRow,
	setQuery,
	setSelectAll,
	setApplyQuery,
	setStats,
} from '../../actions';
import colors from '../theme/colors';

const InfoContainer = styled(Flex)`
	min-height: 150px;
	position: absolute;
	top: 0;
	left: 2px;
	right: 2px;
	bottom: 2px
	z-index: 1000px;
	background: ${colors.white};
`;

type Props = {
	reactiveListKey: number,
	sortField: string,
	sortOrder: string,
	pageSize: number,
	termsAggregationColumns: any,
	onSelectedRows: any => void,
	onSetUpdatingRow: any => void,
	onSetQuery: any => void,
	mappings: any,
	appname: string,
	height: number,
	width: number,
	headerRef: any,
	onSetSelectAll: boolean => void,
	onSetApplyQuery: boolean => void,
	onSetStats: any => void,
	version: number,
};

type State = {
	hasMounted: boolean,
};

class ResultSet extends React.Component<Props, State> {
	state = {
		hasMounted: true,
	};

	shouldComponentUpdate(nextProps) {
		if (nextProps.reactiveListKey !== this.props.reactiveListKey) {
			this.setMountState(false);
			setTimeout(() => {
				this.setMountState(true);
			});

			return false;
		}
		return true;
	}

	setMountState = hasMounted => {
		this.setState({
			hasMounted,
		});
	};

	render() {
		const {
			reactiveListKey,
			sortField,
			sortOrder,
			pageSize,
			termsAggregationColumns,
			onSelectedRows,
			onSetUpdatingRow,
			onSetQuery,
			mappings,
			appname,
			height,
			width,
			headerRef,
			onSetSelectAll,
			onSetApplyQuery,
			onSetStats,
			version,
		} = this.props;

		const { results } = getUrlParams(window.location.search);
		const currentPage = parseInt(results || 1, 10);
		const { hasMounted } = this.state;
		const defaultQuery = {
			sort: [
				{
					[sortField]: { order: sortOrder },
					[version > 5 ? '_id' : '_uid']: {
						order: sortOrder,
					},
				},
			],
		};

		if (version >= 7) {
			// $FlowFixMe
			defaultQuery.track_total_hits = true;
		}
		return (
			hasMounted && (
				<ReactiveList
					key={String(reactiveListKey)}
					componentId="results"
					dataField={sortField}
					sortBy={sortOrder}
					pagination
					size={pageSize}
					showResultStats
					URLParams
					currentPage={currentPage}
					defaultQuery={() => defaultQuery}
					react={{
						and: [
							'GlobalSearch',
							...termsAggregationColumns,
							'indexField',
							'typeField',
						],
					}}
					style={{
						position: 'relative',
						overflow: 'visible',
					}}
					innerClass={{
						poweredBy: css({
							display: 'none',
						}),
						pagination: css({
							position: 'fixed',
							right: 40,
							zIndex: 105,
							'.active': {
								backgroundColor: `${colors.primary} !important`,
							},
						}),
					}}
					onPageChange={() => {
						onSelectedRows([]);
						onSetUpdatingRow(null);
						onSetSelectAll(false);
						onSetApplyQuery(false);
					}}
					onData={({ resultStats }) => {
						const { numberOfResults, ...rest } = resultStats;
						onSetStats({
							totalResults:
								typeof numberOfResults === 'object'
									? numberOfResults.value
									: numberOfResults,
							...rest,
						});
					}}
					renderResultStats={stats => (
						<Flex
							justifyContent="center"
							alignItems="center"
							css={{
								display: 'none',
								[mediaMin.medium]: {
									display: 'block',
									position: 'absolute',
									right: '390px',
									height: '32px',
									fontSize: '14px',
									padding: '0 15px',
									lineHeight: '1.5',
									textAlign: 'center',
									bottom: -45,
								},
							}}
						>
							Showing{' '}
							{numberWithCommas(stats.displayedResults)} of
							total{' '}

								{numberWithCommas(
									typeof stats.numberOfResults === 'object'
										? stats.numberOfResults.value
										: stats.numberOfResults,
								)}

						</Flex>
					)}
					onQueryChange={(prevQuery, nextQuery) => {
						onSetQuery(nextQuery);
						onSetSelectAll(false);
						onSetApplyQuery(false);
					}}
				>
					{({ data, loading }) => (
						<>
							{loading && (
								<InfoContainer
									justifyContent="center"
									css={{
										zIndex: 1000,
									}}
									id="spinner"
								>
									<Loader />
								</InfoContainer>
							)}
							{data && data.length ? (
								<DataTable
									key={data.length ? data[0]._id : '0'}
									data={data}
									mappings={mappings[appname]}
									height={height}
									width={width}
									headerRef={headerRef}
								/>
							) : null}
						</>
					)}
				</ReactiveList>
			)
		);
	}
}

const mapStateToProps = state => {
	const { field: sortField, order: sortOrder } = getSort(state);
	return {
		appname: getAppname(state),
		termsAggregationColumns: getTermsAggregationColumns(state),
		sortField,
		sortOrder,
		pageSize: getPageSize(state),
		reactiveListKey: getReactiveListKey(state),
		mappings: getMappings(state),
		version: getVersion(state),
	};
};

const mapDispatchToProps = {
	onSelectedRows: setSelectedRows,
	onSetUpdatingRow: setUpdatingRow,
	onSetQuery: setQuery,
	onSetSelectAll: setSelectAll,
	onSetApplyQuery: setApplyQuery,
	onSetStats: setStats,
};

export default connect(
	mapStateToProps,
	mapDispatchToProps,
)(ResultSet);
<commit_msg>fix: highligting in edit mode<commit_after>// @flow

import React from 'react';
import { ReactiveList } from '@appbaseio/reactivesearch';
import { connect } from 'react-redux';
import styled, { css } from 'react-emotion';
import { mediaMin } from '@divyanshu013/media';

import DataTable from '../DataTable';
import Flex from '../Flex';
import Loader from '../Loader';

import { numberWithCommas, getUrlParams } from '../../utils';
import { getSort } from '../../reducers/sort';
import { getPageSize } from '../../reducers/pageSize';
import { getAppname } from '../../reducers/app';
import { getReactiveListKey } from '../../reducers/data';
import { getVersion } from '../../reducers/version';
import {
	getTermsAggregationColumns,
	getMappings,
} from '../../reducers/mappings';
import {
	setSelectedRows,
	setUpdatingRow,
	setQuery,
	setSelectAll,
	setApplyQuery,
	setStats,
} from '../../actions';
import colors from '../theme/colors';
import { getMode } from '../../reducers/mode';

const InfoContainer = styled(Flex)`
	min-height: 150px;
	position: absolute;
	top: 0;
	left: 2px;
	right: 2px;
	bottom: 2px
	z-index: 1000px;
	background: ${colors.white};
`;

type Props = {
	reactiveListKey: number,
	sortField: string,
	sortOrder: string,
	pageSize: number,
	termsAggregationColumns: any,
	onSelectedRows: any => void,
	onSetUpdatingRow: any => void,
	onSetQuery: any => void,
	mappings: any,
	appname: string,
	height: number,
	width: number,
	headerRef: any,
	onSetSelectAll: boolean => void,
	onSetApplyQuery: boolean => void,
	onSetStats: any => void,
	version: number,
	mode: string,
};

type State = {
	hasMounted: boolean,
};

class ResultSet extends React.Component<Props, State> {
	state = {
		hasMounted: true,
	};

	shouldComponentUpdate(nextProps) {
		if (
			nextProps.reactiveListKey !== this.props.reactiveListKey ||
			nextProps.mode !== this.props.mode
		) {
			this.setMountState(false);
			setTimeout(() => {
				this.setMountState(true);
			});

			return false;
		}
		return true;
	}

	setMountState = hasMounted => {
		this.setState({
			hasMounted,
		});
	};

	render() {
		const {
			reactiveListKey,
			sortField,
			sortOrder,
			pageSize,
			termsAggregationColumns,
			onSelectedRows,
			onSetUpdatingRow,
			onSetQuery,
			mappings,
			appname,
			height,
			width,
			headerRef,
			onSetSelectAll,
			onSetApplyQuery,
			onSetStats,
			version,
		} = this.props;

		const { results } = getUrlParams(window.location.search);
		const currentPage = parseInt(results || 1, 10);
		const { hasMounted } = this.state;
		const defaultQuery = {
			sort: [
				{
					[sortField]: { order: sortOrder },
					[version > 5 ? '_id' : '_uid']: {
						order: sortOrder,
					},
				},
			],
		};

		if (version >= 7) {
			// $FlowFixMe
			defaultQuery.track_total_hits = true;
		}
		return (
			hasMounted && (
				<ReactiveList
					key={String(reactiveListKey)}
					componentId="results"
					dataField={sortField}
					sortBy={sortOrder}
					pagination
					size={pageSize}
					showResultStats
					URLParams
					currentPage={currentPage}
					defaultQuery={() => defaultQuery}
					react={{
						and: [
							'GlobalSearch',
							...termsAggregationColumns,
							'indexField',
							'typeField',
						],
					}}
					style={{
						position: 'relative',
						overflow: 'visible',
					}}
					innerClass={{
						poweredBy: css({
							display: 'none',
						}),
						pagination: css({
							position: 'fixed',
							right: 40,
							zIndex: 105,
							'.active': {
								backgroundColor: `${colors.primary} !important`,
							},
						}),
					}}
					onPageChange={() => {
						onSelectedRows([]);
						onSetUpdatingRow(null);
						onSetSelectAll(false);
						onSetApplyQuery(false);
					}}
					onData={({ resultStats }) => {
						const { numberOfResults, ...rest } = resultStats;
						onSetStats({
							totalResults:
								typeof numberOfResults === 'object'
									? numberOfResults.value
									: numberOfResults,
							...rest,
						});
					}}
					renderResultStats={stats => (
						<Flex
							justifyContent="center"
							alignItems="center"
							css={{
								display: 'none',
								[mediaMin.medium]: {
									display: 'block',
									position: 'absolute',
									right: '390px',
									height: '32px',
									fontSize: '14px',
									padding: '0 15px',
									lineHeight: '1.5',
									textAlign: 'center',
									bottom: -45,
								},
							}}
						>
							Showing{' '}
							{numberWithCommas(stats.displayedResults)} of
							total{' '}

								{numberWithCommas(
									typeof stats.numberOfResults === 'object'
										? stats.numberOfResults.value
										: stats.numberOfResults,
								)}

						</Flex>
					)}
					onQueryChange={(prevQuery, nextQuery) => {
						onSetQuery(nextQuery);
						onSetSelectAll(false);
						onSetApplyQuery(false);
					}}
				>
					{({ data, loading }) => (
						<>
							{loading && (
								<InfoContainer
									justifyContent="center"
									css={{
										zIndex: 1000,
									}}
									id="spinner"
								>
									<Loader />
								</InfoContainer>
							)}
							{data && data.length ? (
								<DataTable
									key={data.length ? data[0]._id : '0'}
									data={data}
									mappings={mappings[appname]}
									height={height}
									width={width}
									headerRef={headerRef}
								/>
							) : null}
						</>
					)}
				</ReactiveList>
			)
		);
	}
}

const mapStateToProps = state => {
	const { field: sortField, order: sortOrder } = getSort(state);
	return {
		appname: getAppname(state),
		termsAggregationColumns: getTermsAggregationColumns(state),
		sortField,
		sortOrder,
		pageSize: getPageSize(state),
		reactiveListKey: getReactiveListKey(state),
		mappings: getMappings(state),
		version: getVersion(state),
		mode: getMode(state),
	};
};

const mapDispatchToProps = {
	onSelectedRows: setSelectedRows,
	onSetUpdatingRow: setUpdatingRow,
	onSetQuery: setQuery,
	onSetSelectAll: setSelectAll,
	onSetApplyQuery: setApplyQuery,
	onSetStats: setStats,
};

export default connect(
	mapStateToProps,
	mapDispatchToProps,
)(ResultSet);
<|endoftext|>


<commit_before>var $db = require(global.cwd + '/lib/mongo');
var debug = require('debug')('wol:leaderboard');
var ranking = require('../ranking');

module.exports = function process(game, dump) {
    var match = require(__dirname + '/lib/parse')(game, dump);

    /* discontinue if no gameId or match is less than 1 minute */
    if (!match.idno || match.dura < 60) return;
    debug('game: %s, idno: %d', game, match.idno);

    // create raw dump entry
    // TODO: check against spid (sender id) to ensure only 1 packet from each player
    // TODO: idno is random but could collide. check if record exists and compare dates
    var $dumps = $db.get(game +'_dumps');
    $dumps.update({idno: match.idno}, {$push: {buffers: match.buffer}}, {upsert: true}, _stats);

    function _stats(err, data) {
        $dumps.find({idno: match.idno}, function(err, doc) {
            if (doc.length > 1) {
                // error scneario, we have two entries for the same game
                // todo: figure out what the hell to do?
                // todo: elimiate duplicates?
                debug('found duplicates! game: %s, idno: %d', game, match.idno);
                return;
            }

            // only continue if this is the first entry for a game
            if (doc[0].buffers && doc[0].buffers.length > 1) return;

            // remove unused properties from game object
            delete match.buffer; /* only used for previous parsing */
            delete match.client; /* unused information about the client */

            /* save match */
            $db.get(game +'_games').insert(match).success(function(doc) {
                debug('game: %s, idno: %d saved!', game, match.idno);

                /* process rankings at a 3 minute delay */
                /* this allows time for all packets to arrive */
                setTimeout(function() {
                    ranking.process(game, match);
                }, 180000);
            });
        });
    }

    return;
};
<commit_msg>lowering process delay to 1.5mins<commit_after>var $db = require(global.cwd + '/lib/mongo');
var debug = require('debug')('wol:leaderboard');
var ranking = require('../ranking');

module.exports = function process(game, dump) {
    var match = require(__dirname + '/lib/parse')(game, dump);

    /* discontinue if no gameId or match is less than 1 minute */
    if (!match.idno || match.dura < 60) return;
    debug('game: %s, idno: %d', game, match.idno);

    // create raw dump entry
    // TODO: check against spid (sender id) to ensure only 1 packet from each player
    // TODO: idno is random but could collide. check if record exists and compare dates
    var $dumps = $db.get(game +'_dumps');
    $dumps.update({idno: match.idno}, {$push: {buffers: match.buffer}}, {upsert: true}, _stats);

    function _stats(err, data) {
        $dumps.find({idno: match.idno}, function(err, doc) {
            if (doc.length > 1) {
                // error scneario, we have two entries for the same game
                // todo: figure out what the hell to do?
                // todo: elimiate duplicates?
                debug('found duplicates! game: %s, idno: %d', game, match.idno);
                return;
            }

            // only continue if this is the first entry for a game
            if (doc[0].buffers && doc[0].buffers.length > 1) return;

            // remove unused properties from game object
            delete match.buffer; /* only used for previous parsing */
            delete match.client; /* unused information about the client */

            /* save match */
            $db.get(game +'_games').insert(match).success(function(doc) {
                debug('game: %s, idno: %d saved!', game, match.idno);

                /* process rankings at a 1.5 minute delay */
                /* this allows time for all packets to arrive */
                setTimeout(function() {
                    ranking.process(game, match);
                }, 90000);
            });
        });
    }

    return;
};
<|endoftext|>


<commit_before>// Endpoint class
function Endpoint(address) {
    var ClosedState = 0;
    var ConnectingState = 1;
    var ActiveState = 2;

    var reconnectTries = 0;

    console.log("connecting to " + address);
    var webSocket = null;
    var state = ClosedState;

    var that = this;

    var incomingMessage = null;

    open();

    function open() {
        if (webSocket != null) {
            webSocket.onopen = null;
            webSocket.onclose = null;
            webSocket.onmessage = null;
        }

        outgoingArray = [];

        webSocket = new window.WebSocket(address, ["WSNetMQ"]);
        webSocket.binaryType = "arraybuffer";
        state = ConnectingState;

        webSocket.onopen = onopen;
        webSocket.onclose = onclose;
        webSocket.onmessage = onmessage;

        reconnectTries++;
    }

    function onopen (e) {
        console.log("WebSocket opened to " + address);
        reconnectTries = 0;

        state = ActiveState;

        if (that.activated != null) {
            that.activated(that);
        }
    };

    function onclose(e) {
        console.log("WebSocket closed " + address);
        var stateBefore = state;
        state = ClosedState;

        if (stateBefore == ActiveState && that.deactivated != null) {
            that.deactivated(that);
        }

        if (reconnectTries > 10) {
            window.setTimeout(open, 2000);
        } else {
            open();
        }
    };

    function onmessage(ev) {
        if (ev.data instanceof Blob) {
            var arrayBuffer;
            var fileReader = new FileReader();
            fileReader.onload = function () {
                processFrame(this.result);
            };
            fileReader.readAsArrayBuffer(ev.data);
        } else if (ev.data instanceof ArrayBuffer) {
            processFrame(ev.data);
        }
        // Other message type are not supported and will just be dropped
    };

    function processFrame(frame) {
        var view = new Uint8Array(frame);
        var more = view[0];

        if (incomingMessage == null) {
            incomingMessage = new JSMQ.Message();
        }

        incomingMessage.addBuffer(view.subarray(1));

        // last message
        if (more == 0) {
            if (that.onMessage != null) {
                that.onMessage(that, incomingMessage);
            }

            incomingMessage = null;
        }
    }

    // activated event, when the socket is open
    this.activated = null;

    // deactivated event
    this.deactivated = null;

    this.onMessage = null;

    this.getIsActive = function() {
        return state == ActiveState;
    };

    this.write = function (message) {
        var messageSize = message.getSize();

        for (var j = 0; j < messageSize; j++) {
            var frame = message.getBuffer(j);

            var data = new Uint8Array(frame.length + 1);
            data[0] = j == messageSize - 1 ? 0 : 1; // set the more byte

            data.set(frame, 1);

            webSocket.send(data);
        }
    };
}

// LoadBalancer

function LB() {
    var endpoints = [];
    var current = 0;
    var isActive = false;

    this.writeActivated = null;

    var that = this;

    this.attach = function(endpoint) {
        endpoints.push(endpoint);

        if (!isActive) {
            isActive = true;

            if (that.writeActivated != null)
                that.writeActivated();
        }
    };

    this.terminated = function(endpoint) {
        var index = endpoints.indexOf(endpoint);

        if (current == endpoints.length - 1) {
            current = 0;
        }

        endpoints.splice(index, 1);
    };

    this.send = function (message) {
        if (endpoints.length == 0) {
            isActive = false;
            return false;
        }

        endpoints[current].write(message);
        current = (current + 1) % endpoints.length;

        return true;
    };

    this.getHasOut = function () {
        if (inprogress)
            return true;

        return endpoints.length > 0;
    };
}

// SocketBase Class

function SocketBase(xattachEndpoint, xendpointTerminated, xhasOut, xsend, xonMessage) {

    this.onMessage = null;
    this.sendReady = null;

    var endpoints = [];

    function onEndpointActivated(endpoint) {
        xattachEndpoint(endpoint);
    }

    function onEndpointDeactivated(endpoint) {
        xendpointTerminated(endpoint);
    }

    this.connect = function (address) {
        var endpoint = new Endpoint(address);
        endpoint.activated = onEndpointActivated;
        endpoint.deactivated = onEndpointDeactivated;
        endpoint.onMessage = xonMessage;
        endpoints.push(endpoint);
    };

    this.disconnect = function(address) {
        // TODO: implement disconnect
    };

    this.isConnected = function() {
        for(i = 0; i < endpoints.length; i++)
            if (!endpoints[i].getIsActive())
                return false;

        return true;
    }

    this.send = function (message) {
        return xsend(message);
    };

    this.getHasOut = function() {
        return xhasOut();
    };
}

// JSMQ namespace
function JSMQ() {

}

JSMQ.Dealer = function() {

    var lb = new LB();

    var that = new SocketBase(xattachEndpoint, xendpointTerminated, xhasOut, xsend, xonMessage);

    lb.writeActivated = function() {
        if (that.sendReady != null) {
            that.sendReady(that);
        }
    };

    function xattachEndpoint(endpoint) {
        lb.attach(endpoint);
    }

    function xendpointTerminated(endpoint) {
        lb.terminated(endpoint);
    }

    function xhasOut() {
        return lb.getHasOut();
    }

    function xsend(message) {
        return lb.send(message);
    }

    function xonMessage(endpoint, message) {
        if (that.onMessage != null) {
            that.onMessage(message);
        }
    }

    return that;
}

JSMQ.Subscriber = function () {

    var that = new SocketBase(xattachEndpoint, xendpointTerminated, xhasOut, xsend, xonMessage);;

    var subscriptions = [];
    var endpoints = [];

    var isActive = false;

    that.subscribe = function (subscription) {

        if (subscription instanceof Uint8Array) {
            // continue
        }
        else if (subscription instanceof ArrayBuffer) {
            subscription = new Uint8Array(subscription);
        } else {
            subscription = StringUtility.StringToUint8Array(String(subscription));
        }

        // TODO: check if the subscription already exist
        subscriptions.push(subscription)

        var message = createSubscriptionMessage(subscription, true);

        for (var i = 0; i < endpoints.length; i++) {
            endpoints[i].write(message);
        }
    }

    that.unsubscribe = function (subscription) {
        if (subscription instanceof Uint8Array) {
            // continue
        }
        else if (subscription instanceof ArrayBuffer) {
            subscription = new Uint8Array(subscription);

        } else {
            subscription = StringUtility.StringToUint8Array(String(subscription));
        }

        for (var j = 0; j < subscriptions.length; j++) {

            if (subscriptions[j].length == subscription.length) {
                var equal = true;

                for (var k = 0; k < subscriptions[j].length; k++) {
                    if (subscriptions[j][k] != subscription[k]) {
                        equal = false;
                        break;
                    }
                }

                if (equal) {
                    subscriptions.splice(j, 1);
                    break;
                }
            }
        }

        var message = createSubscriptionMessage(subscription, false);

        for (var i = 0; i < endpoints.length; i++) {
            endpoints[i].write(message);
        }
    }

    function createSubscriptionMessage(subscription, subscribe) {
        var frame = new Uint8Array(subscription.length + 1);
        frame[0] = subscribe ? 1 : 0;
        frame.set(subscription, 1);

        var message = new JSMQ.Message();
        message.addBuffer(frame);

        return message;
    }

    function xattachEndpoint(endpoint) {
        endpoints.push(endpoint);

        for (var i = 0; i < subscriptions.length; i++) {
            var message = createSubscriptionMessage(subscriptions[i], true);

            endpoint.write(message);
        }

        if (!isActive) {
            isActive = true;

            if (that.sendReady != null) {
                that.sendReady(that);
            }
        }
    }

    function xendpointTerminated(endpoint) {
        var index = endpoints.indexOf(endpoint);
        endpoints.splice(index, 1);
    }

    function xhasOut() {
        return false;
    }

    function xsend(message, more) {
        throw new "Send not supported on sub socket";
    }

    function xonMessage(endpoint, message) {
        if (that.onMessage != null) {
            that.onMessage(message);
        }
    }

    return that;
}

JSMQ.Message = function () {
    var frames = [];

    this.getSize = function() {
        return frames.length;
    }

    // add string at the begining of the message
    this.prependString = function(str) {
        str = String(str);

        // one more byte is saved for the more byte
        var buffer = new Uint8Array(str.length);

        StringUtility.StringToUint8Array(str, buffer);

        frames.splice(0, 0, buffer);
    }

    // add the string at the end of the message
    this.addString = function(str) {
        str = String(str);

        // one more byte is saved for the more byte
        var buffer = new Uint8Array(str.length);

        StringUtility.StringToUint8Array(str, buffer);
        frames.push(buffer);
    }

    // pop a string from the begining of the message
    this.popString = function() {
        var frame = this.popBuffer();

        return StringUtility.Uint8ArrayToString(frame);
    }

    this.popBuffer = function() {
        var frame = frames[0];
        frames.splice(0, 1);

        return frame;
    }

    // addd buffer at the end of the message
    this.addBuffer = function (buffer) {

        if (buffer instanceof ArrayBuffer) {
            frames.push(new Uint8Array(buffer));
        }
        else if (buffer instanceof Uint8Array) {
            frames.push(buffer);
        } else {
            throw new "unknown buffer type";
        }
    }

    // return Uint8Array at location i
    this.getBuffer = function(i) {
        return frames[i];
    }
}

function StringUtility()
{ }

StringUtility.StringToUint8Array = function (str, buffer) {
    if (typeof buffer === 'undefined') {
        buffer = new Uint8Array(str.length);
    }

    for (var i = 0, strLen = str.length; i < strLen; i++) {
        var char = str.charCodeAt(i);

        if (char > 255) {
            // only ASCII are supported at the moment, we will put ? instead
            buffer[i] = "?".charCodeAt();
        } else {
            buffer[i] = char;
        }
    }

    return buffer;
}

StringUtility.Uint8ArrayToString = function(buffer) {
    return String.fromCharCode.apply(null, buffer);
}<commit_msg>Add isConnecting method to SocketBase and getIsConnecting to Endpoint<commit_after>// Endpoint class
function Endpoint(address) {
    var ClosedState = 0;
    var ConnectingState = 1;
    var ActiveState = 2;

    var reconnectTries = 0;

    console.log("connecting to " + address);
    var webSocket = null;
    var state = ClosedState;

    var that = this;

    var incomingMessage = null;

    open();

    function open() {
        if (webSocket != null) {
            webSocket.onopen = null;
            webSocket.onclose = null;
            webSocket.onmessage = null;
        }

        outgoingArray = [];

        webSocket = new window.WebSocket(address, ["WSNetMQ"]);
        webSocket.binaryType = "arraybuffer";
        state = ConnectingState;

        webSocket.onopen = onopen;
        webSocket.onclose = onclose;
        webSocket.onmessage = onmessage;

        reconnectTries++;
    }

    function onopen (e) {
        console.log("WebSocket opened to " + address);
        reconnectTries = 0;

        state = ActiveState;

        if (that.activated != null) {
            that.activated(that);
        }
    };

    function onclose(e) {
        console.log("WebSocket closed " + address);
        var stateBefore = state;
        state = ClosedState;

        if (stateBefore == ActiveState && that.deactivated != null) {
            that.deactivated(that);
        }

        if (reconnectTries > 10) {
            window.setTimeout(open, 2000);
        } else {
            open();
        }
    };

    function onmessage(ev) {
        if (ev.data instanceof Blob) {
            var arrayBuffer;
            var fileReader = new FileReader();
            fileReader.onload = function () {
                processFrame(this.result);
            };
            fileReader.readAsArrayBuffer(ev.data);
        } else if (ev.data instanceof ArrayBuffer) {
            processFrame(ev.data);
        }
        // Other message type are not supported and will just be dropped
    };

    function processFrame(frame) {
        var view = new Uint8Array(frame);
        var more = view[0];

        if (incomingMessage == null) {
            incomingMessage = new JSMQ.Message();
        }

        incomingMessage.addBuffer(view.subarray(1));

        // last message
        if (more == 0) {
            if (that.onMessage != null) {
                that.onMessage(that, incomingMessage);
            }

            incomingMessage = null;
        }
    }

    // activated event, when the socket is open
    this.activated = null;

    // deactivated event
    this.deactivated = null;

    this.onMessage = null;

    this.getIsActive = function() {
        return state == ActiveState;
    };

    this.getIsConnecting = function() {
        return state == ConnectingState;
    }

    this.write = function (message) {
        var messageSize = message.getSize();

        for (var j = 0; j < messageSize; j++) {
            var frame = message.getBuffer(j);

            var data = new Uint8Array(frame.length + 1);
            data[0] = j == messageSize - 1 ? 0 : 1; // set the more byte

            data.set(frame, 1);

            webSocket.send(data);
        }
    };
}

// LoadBalancer

function LB() {
    var endpoints = [];
    var current = 0;
    var isActive = false;

    this.writeActivated = null;

    var that = this;

    this.attach = function(endpoint) {
        endpoints.push(endpoint);

        if (!isActive) {
            isActive = true;

            if (that.writeActivated != null)
                that.writeActivated();
        }
    };

    this.terminated = function(endpoint) {
        var index = endpoints.indexOf(endpoint);

        if (current == endpoints.length - 1) {
            current = 0;
        }

        endpoints.splice(index, 1);
    };

    this.send = function (message) {
        if (endpoints.length == 0) {
            isActive = false;
            return false;
        }

        endpoints[current].write(message);
        current = (current + 1) % endpoints.length;

        return true;
    };

    this.getHasOut = function () {
        if (inprogress)
            return true;

        return endpoints.length > 0;
    };
}

// SocketBase Class

function SocketBase(xattachEndpoint, xendpointTerminated, xhasOut, xsend, xonMessage) {

    this.onMessage = null;
    this.sendReady = null;

    var endpoints = [];

    function onEndpointActivated(endpoint) {
        xattachEndpoint(endpoint);
    }

    function onEndpointDeactivated(endpoint) {
        xendpointTerminated(endpoint);
    }

    this.connect = function (address) {
        var endpoint = new Endpoint(address);
        endpoint.activated = onEndpointActivated;
        endpoint.deactivated = onEndpointDeactivated;
        endpoint.onMessage = xonMessage;
        endpoints.push(endpoint);
    };

    this.disconnect = function(address) {
        // TODO: implement disconnect
    };

    this.isConnected = function() {
        for(i = 0; i < endpoints.length; i++)
            if (!endpoints[i].getIsActive())
                return false;

        return true;
    }

    this.isConnecting = function() {
        for(i = 0; i < endpoints.length; i++)
            if (!endpoints[i].getIsConnecting())
                return false;

        return true;
    }

    this.send = function (message) {
        return xsend(message);
    };

    this.getHasOut = function() {
        return xhasOut();
    };
}

// JSMQ namespace
function JSMQ() {

}

JSMQ.Dealer = function() {

    var lb = new LB();

    var that = new SocketBase(xattachEndpoint, xendpointTerminated, xhasOut, xsend, xonMessage);

    lb.writeActivated = function() {
        if (that.sendReady != null) {
            that.sendReady(that);
        }
    };

    function xattachEndpoint(endpoint) {
        lb.attach(endpoint);
    }

    function xendpointTerminated(endpoint) {
        lb.terminated(endpoint);
    }

    function xhasOut() {
        return lb.getHasOut();
    }

    function xsend(message) {
        return lb.send(message);
    }

    function xonMessage(endpoint, message) {
        if (that.onMessage != null) {
            that.onMessage(message);
        }
    }

    return that;
}

JSMQ.Subscriber = function () {

    var that = new SocketBase(xattachEndpoint, xendpointTerminated, xhasOut, xsend, xonMessage);;

    var subscriptions = [];
    var endpoints = [];

    var isActive = false;

    that.subscribe = function (subscription) {

        if (subscription instanceof Uint8Array) {
            // continue
        }
        else if (subscription instanceof ArrayBuffer) {
            subscription = new Uint8Array(subscription);
        } else {
            subscription = StringUtility.StringToUint8Array(String(subscription));
        }

        // TODO: check if the subscription already exist
        subscriptions.push(subscription)

        var message = createSubscriptionMessage(subscription, true);

        for (var i = 0; i < endpoints.length; i++) {
            endpoints[i].write(message);
        }
    }

    that.unsubscribe = function (subscription) {
        if (subscription instanceof Uint8Array) {
            // continue
        }
        else if (subscription instanceof ArrayBuffer) {
            subscription = new Uint8Array(subscription);

        } else {
            subscription = StringUtility.StringToUint8Array(String(subscription));
        }

        for (var j = 0; j < subscriptions.length; j++) {

            if (subscriptions[j].length == subscription.length) {
                var equal = true;

                for (var k = 0; k < subscriptions[j].length; k++) {
                    if (subscriptions[j][k] != subscription[k]) {
                        equal = false;
                        break;
                    }
                }

                if (equal) {
                    subscriptions.splice(j, 1);
                    break;
                }
            }
        }

        var message = createSubscriptionMessage(subscription, false);

        for (var i = 0; i < endpoints.length; i++) {
            endpoints[i].write(message);
        }
    }

    function createSubscriptionMessage(subscription, subscribe) {
        var frame = new Uint8Array(subscription.length + 1);
        frame[0] = subscribe ? 1 : 0;
        frame.set(subscription, 1);

        var message = new JSMQ.Message();
        message.addBuffer(frame);

        return message;
    }

    function xattachEndpoint(endpoint) {
        endpoints.push(endpoint);

        for (var i = 0; i < subscriptions.length; i++) {
            var message = createSubscriptionMessage(subscriptions[i], true);

            endpoint.write(message);
        }

        if (!isActive) {
            isActive = true;

            if (that.sendReady != null) {
                that.sendReady(that);
            }
        }
    }

    function xendpointTerminated(endpoint) {
        var index = endpoints.indexOf(endpoint);
        endpoints.splice(index, 1);
    }

    function xhasOut() {
        return false;
    }

    function xsend(message, more) {
        throw new "Send not supported on sub socket";
    }

    function xonMessage(endpoint, message) {
        if (that.onMessage != null) {
            that.onMessage(message);
        }
    }

    return that;
}

JSMQ.Message = function () {
    var frames = [];

    this.getSize = function() {
        return frames.length;
    }

    // add string at the begining of the message
    this.prependString = function(str) {
        str = String(str);

        // one more byte is saved for the more byte
        var buffer = new Uint8Array(str.length);

        StringUtility.StringToUint8Array(str, buffer);

        frames.splice(0, 0, buffer);
    }

    // add the string at the end of the message
    this.addString = function(str) {
        str = String(str);

        // one more byte is saved for the more byte
        var buffer = new Uint8Array(str.length);

        StringUtility.StringToUint8Array(str, buffer);
        frames.push(buffer);
    }

    // pop a string from the begining of the message
    this.popString = function() {
        var frame = this.popBuffer();

        return StringUtility.Uint8ArrayToString(frame);
    }

    this.popBuffer = function() {
        var frame = frames[0];
        frames.splice(0, 1);

        return frame;
    }

    // addd buffer at the end of the message
    this.addBuffer = function (buffer) {

        if (buffer instanceof ArrayBuffer) {
            frames.push(new Uint8Array(buffer));
        }
        else if (buffer instanceof Uint8Array) {
            frames.push(buffer);
        } else {
            throw new "unknown buffer type";
        }
    }

    // return Uint8Array at location i
    this.getBuffer = function(i) {
        return frames[i];
    }
}

function StringUtility()
{ }

StringUtility.StringToUint8Array = function (str, buffer) {
    if (typeof buffer === 'undefined') {
        buffer = new Uint8Array(str.length);
    }

    for (var i = 0, strLen = str.length; i < strLen; i++) {
        var char = str.charCodeAt(i);

        if (char > 255) {
            // only ASCII are supported at the moment, we will put ? instead
            buffer[i] = "?".charCodeAt();
        } else {
            buffer[i] = char;
        }
    }

    return buffer;
}

StringUtility.Uint8ArrayToString = function(buffer) {
    return String.fromCharCode.apply(null, buffer);
}<|endoftext|>


<commit_before>var $db = require(global.cwd + '/lib/mongo'),
    debug = require('debug')('wol:leaderboard'),
    ranking = require('../ranking'),
    MATCH_DELAY = parseInt(process.env.MATCH_DELAY) || 90000;

/* match cache for quick comparison */
global.matches = {};

var games = {
    ra: require(global.cwd + '/lib/games/lib/ra'),
    ts: require(global.cwd + '/lib/games/lib/ts')
};

module.exports = function process(game, dump) {
    var match = require(__dirname + '/lib/parse')(game, dump);

    /* TS Scenario: note whether game map is mod or ww */
    if (game === 'ts') {
        match.settings = games[game].official(match.settings);
        if (!match.settings.official) {
            game = 'tsm'; /* tiberian sun mod map */
        }
    }

    /* discontinue if no gameId or match is less than 1 minute */
    if (!match.idno || match.dura < 60) return;
    debug('game: %s, idno: %d game received', game, match.idno);
    if (!global.matches[game]) global.matches[game] = {};
    global.matches[game][match.idno] = global.matches[game][match.idno] || [];

    // create raw dump entry
    // TODO: check against spid (sender id) to ensure only 1 packet from each player
    // TODO: idno is random but could collide. check if record exists and compare dates
    var $dumps = $db.get(game +'_dumps');
    $dumps.update({idno: match.idno}, {$push: {buffers: match.buffer}}, {upsert: true}).error(function(err) {
        console.log('match/process dump entry error');
        console.log('game: %s, match: %d', game, match.idno);
        console.log('buffer: %s', match.buffer.toString('hex'));
        console.dir(err);
    });

    global.matches[game][match.idno].push({
        unid: match.client.unid
    });

    // only continue if this is the first entry for a game
    if (global.matches[game][match.idno].length > 1) return;

    // remove unused properties from game object
    delete match.buffer; /* only used for previous parsing */
    delete match.client; /* unused information about the client */

    /* save match */
    var p = $db.get(game +'_games').insert(match);
    p.success(function(doc) {
        debug('game: %s, idno: %d game saved!', game, match.idno);

        /* process rankings at a 1.5 minute delay */
        /* this allows time for all packets to arrive */
        setTimeout(function() {
            ranking.process(game, match);
        }, MATCH_DELAY);
    });

    p.error(function(err) {
        console.log('error');
        console.dir(err);
    });

    return;
};
<commit_msg>remove entry from global matches at rank processing<commit_after>var $db = require(global.cwd + '/lib/mongo'),
    debug = require('debug')('wol:leaderboard'),
    ranking = require('../ranking'),
    MATCH_DELAY = parseInt(process.env.MATCH_DELAY) || 90000;

/* match cache for quick comparison */
global.matches = {};

var games = {
    ra: require(global.cwd + '/lib/games/lib/ra'),
    ts: require(global.cwd + '/lib/games/lib/ts')
};

module.exports = function process(game, dump) {
    var match = require(__dirname + '/lib/parse')(game, dump);

    /* TS Scenario: note whether game map is mod or ww */
    if (game === 'ts') {
        match.settings = games[game].official(match.settings);
        if (!match.settings.official) {
            game = 'tsm'; /* tiberian sun mod map */
        }
    }

    /* discontinue if no gameId or match is less than 1 minute */
    if (!match.idno || match.dura < 60) return;
    debug('game: %s, idno: %d game received', game, match.idno);
    if (!global.matches[game]) global.matches[game] = {};
    global.matches[game][match.idno] = global.matches[game][match.idno] || [];

    // create raw dump entry
    // TODO: check against spid (sender id) to ensure only 1 packet from each player
    // TODO: idno is random but could collide. check if record exists and compare dates
    var $dumps = $db.get(game +'_dumps');
    $dumps.update({idno: match.idno}, {$push: {buffers: match.buffer}}, {upsert: true}).error(function(err) {
        console.log('match/process dump entry error');
        console.log('game: %s, match: %d', game, match.idno);
        console.log('buffer: %s', match.buffer.toString('hex'));
        console.dir(err);
    });

    global.matches[game][match.idno].push({
        unid: match.client.unid
    });

    // only continue if this is the first entry for a game
    if (global.matches[game][match.idno].length > 1) return;

    // remove unused properties from game object
    delete match.buffer; /* only used for previous parsing */
    delete match.client; /* unused information about the client */

    /* save match */
    var p = $db.get(game +'_games').insert(match);
    p.success(function(doc) {
        debug('game: %s, idno: %d game saved!', game, match.idno);

        /* process rankings at a 1.5 minute delay */
        /* this allows time for all packets to arrive */
        setTimeout(function() {
            delete global.matches[game][match.idno];
            ranking.process(game, match);
        }, MATCH_DELAY);
    });

    p.error(function(err) {
        console.log('error');
        console.dir(err);
    });

    return;
};
<|endoftext|>