--- /dev/null
+^9Definitions^0
+Service: the XonStat player statistics system and the Xonotic forums provided by Team Xonotic
+You: the user of the service
+We: the past and present contributors to Xonotic
+
+^9Terms^0
+By accessing the services at https://stats.xonotic.org and https://forums.xonotic.org, you are agreeing to be bound by these terms of service, all applicable laws and regulations, and agree that you are responsible for compliance with any applicable local laws. If you do not agree with any of these terms, you are prohibited from using or accessing this site.
+
+By using our services, you agree to allow user identifiable information to be presented within the system for the purpose of:
+
+- communicating with others in the community directly (e.g. via PM) or indirectly (e.g. via a public post)
+- establishing user profiles
+- recording game results
+- collecting usage information
+- running ad hoc reports
+
+We reserve the right to:
+- Moderate the service using automated or manual means.
+- Appoint others outside of Team Xonotic to moderate the service on an as-needed basis.
+- Discontinue, interrupt, or change the service without any advance notice or consent.
+- Release full or partial versions of the underlying dataset, provided it has been anonymized.
+
+^9Privacy Policy^0
+Your privacy is important to us. It is Team Xonotic’s policy to respect your privacy regarding any information we collect from you across our web properties https://stats.xonotic.org and https://forums.xonotic.org, along with any other sites we own and operate.
+
+We only collect information when we truly need it to provide a service to you and the community at large. We collect it by fair and lawful means, with your knowledge and consent via configurable, in-game options (cl_allow_uidtracking and cl_allow_uid2name for XonStat) or via signup forms (for the forums). We also let you know why we’re collecting it and how it will be used. You are free to refuse our request for your personal information by not opting in to either of these services.
+
+We retain the collected information for as long as necessary to provide you and the community at large with the requested service. We will protect that data with all means at our disposal to avoid unauthorised access, disclosure, copying, use or modification. In such cases where data sets are released to the public, we will ensure that they are anonymized such that client-identifiable key information is no longer present.
+
+We don’t share any personally identifying information publicly or with third-parties, except when required to by law.
+
+Usage of our player statistics system and other web properties constitutes acceptance of the policies outlined in this document. If you have any questions about how we handle user data and personal information, feel free to contact us.
+
+This policy is effective as of 16 June 2018.
#include <menu/xonotic/dialog.qc>
#include <menu/xonotic/dialog_credits.qc>
#include <menu/xonotic/dialog_disconnect.qc>
+#include <menu/xonotic/dialog_termsofservice.qc>
#include <menu/xonotic/dialog_firstrun.qc>
#include <menu/xonotic/dialog_hudpanel_ammo.qc>
#include <menu/xonotic/dialog_hudpanel_centerprint.qc>
#include <menu/xonotic/dialog.qh>
#include <menu/xonotic/dialog_credits.qh>
#include <menu/xonotic/dialog_disconnect.qc>
+#include <menu/xonotic/dialog_termsofservice.qh>
#include <menu/xonotic/dialog_firstrun.qh>
#include <menu/xonotic/dialog_hudpanel_ammo.qh>
#include <menu/xonotic/dialog_hudpanel_centerprint.qh>
#include "charmap.qh"
#include "commandbutton.qh"
+bool XonoticFirstRunDialog_shouldShow()
+{
+ return cvar_string("_cl_name") == cvar_defstring("_cl_name");
+}
+
float CheckFirstRunButton(entity me)
{
if(cvar_string("_cl_name") != cvar_defstring("_cl_name"))
#include "rootdialog.qh"
CLASS(XonoticFirstRunDialog, XonoticRootDialog)
METHOD(XonoticFirstRunDialog, fill, void(entity));
+ METHOD(XonoticFirstRunDialog, shouldShow, bool());
ATTRIB(XonoticFirstRunDialog, title, string, _("Welcome"));
ATTRIB(XonoticFirstRunDialog, color, vector, SKINCOLOR_DIALOG_FIRSTRUN);
ATTRIB(XonoticFirstRunDialog, intendedWidth, float, 0.7);
--- /dev/null
+#include "dialog_termsofservice.qh"
+
+#include "../menu.qh"
+#include "dialog_firstrun.qh"
+#include "textbox.qh"
+#include "button.qh"
+
+void Close_Clicked(entity btn, entity me)
+{
+ cvar_set("_termsofservice_accepted", "1");
+ localcmd("saveconfig");
+ if (main.firstRunDialog.shouldShow())
+ {
+ main.dialogToShow = main.firstRunDialog;
+ }
+ Dialog_Close(btn, me);
+}
+
+void DontAccept_Clicked(entity btn, entity me)
+{
+ localcmd("quit");
+}
+
+void XonoticToSDialog_loadXonoticToS(entity me)
+{
+ string ToSText = "";
+ int fh = fopen("TermsOfService", FILE_READ);
+ if (fh >= 0)
+ {
+ for (string line; (line = fgets(fh)); ) {
+ if (ToSText != "")
+ {
+ ToSText = strcat(ToSText, "\n", line);
+ }
+ else
+ {
+ ToSText = line;
+ }
+ }
+ }
+ fclose(fh);
+ me.textBox.setText(me.textBox, ToSText);
+}
+
+bool XonoticToSDialog_shouldShow()
+{
+ return !autocvar__termsofservice_accepted;
+}
+
+void XonoticToSDialog_fill(entity me)
+{
+ entity e;
+
+ me.TR(me);
+ me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Welcome to Xonotic! Please read the following Terms of Service")));
+ e.allowWrap = 1;
+
+ me.TR(me);
+ me.TR(me);
+ me.TD(me, me.rows - 4, me.columns, me.textBox = makeXonoticTextBox());
+ me.loadXonoticToS(me);
+
+ me.TR(me);
+ me.gotoRC(me, me.rows - 1, 0);
+ me.TD(me, 1, me.columns/2, e = makeXonoticButton(_("Accept"), '0 0 0'));
+ e.onClick = Close_Clicked;
+ e.onClickEntity = me;
+ me.TD(me, 1, me.columns/2, e = makeXonoticButton(_("Don't accept & quit"), '0 0 0'));
+ e.onClick = DontAccept_Clicked;
+ e.onClickEntity = me;
+}
+
--- /dev/null
+#pragma once
+
+bool autocvar__termsofservice_accepted = false;
+
+#include "rootdialog.qh"
+CLASS(XonoticToSDialog, XonoticRootDialog)
+ METHOD(XonoticToSDialog, shouldShow, bool());
+ METHOD(XonoticToSDialog, fill, void(entity));
+ METHOD(XonoticToSDialog, loadXonoticToS, void(entity));
+ ATTRIB(XonoticToSDialog, title, string, _("Terms of Service"));
+ ATTRIB(XonoticToSDialog, color, vector, SKINCOLOR_DIALOG_FIRSTRUN);
+ ATTRIB(XonoticToSDialog, intendedWidth, float, 0.8);
+ ATTRIB(XonoticToSDialog, rows, float, 16);
+ ATTRIB(XonoticToSDialog, columns, float, 6.2);
+ ATTRIB(XonoticToSDialog, name, string, "TermsOfService");
+ ATTRIB(XonoticToSDialog, textBox, entity);
+
+ ATTRIB(XonoticToSDialog, closable, float, 0);
+ENDCLASS(XonoticToSDialog)
#include "nexposee.qh"
#include "inputbox.qh"
+#include "dialog_termsofservice.qh"
#include "dialog_firstrun.qh"
#include "dialog_hudsetup_exit.qh"
#include "dialog_hudpanel_notification.qh"
//-------------------------------------
// Part of Disconnect Dialog button:
- // In case of this function is recalling every time, need to use condition of visibility
-
- if (me.disconnectDialogVisibility && !(gamestatus & (GAME_ISSERVER | GAME_CONNECTED)))
+ // In case of this function is recalling every time, need to use condition of visibility
+
+ if (me.disconnectDialogVisibility && !(gamestatus & (GAME_ISSERVER | GAME_CONNECTED)))
{
- // If gamestate is not "ingame" (and it is a first "frame" of drawing (or dialog is visible)),
+ // If gamestate is not "ingame" (and it is a first "frame" of drawing (or dialog is visible)),
// disconnect button is unnecessary, remove it
me.removeItem(me.mainNexposee, me.disconnectDialog);
me.disconnectDialogVisibility = 0;
} else if(!me.disconnectDialogVisibility && (gamestatus & (GAME_ISSERVER | GAME_CONNECTED))) {
-
- // If gamestate is "ingame" (and dialog is not visible),
+
+ // If gamestate is "ingame" (and dialog is not visible),
// make disconnect button visible
entity n, i;
n = me.mainNexposee;
me.disconnectDialogVisibility = 1;
}
- // I haven't found the best solution for making button visible.
+ // I haven't found the best solution for making button visible.
// Alpha channel is the worst thing, because dialog with alpha is also clickable
//-------------------------------------
}
{
entity n, i;
+ // terms of service dialog
+ me.ToSDialog = i = NEW(XonoticToSDialog);
+ i.configureDialog(i);
+ me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+
// dialog run upon startup
me.firstRunDialog = i = NEW(XonoticFirstRunDialog);
i.configureDialog(i);
// main dialogs/windows
me.mainNexposee = n = NEW(XonoticNexposee);
-
+
/*
if(checkextension("DP_GECKO_SUPPORT"))
{
n.setNexposee(n, i, '0.1 0.1 0', SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y);
}
*/
-
+
i = NEW(XonoticSingleplayerDialog);
i.configureDialog(i);
n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
n.setNexposee(n, i, '0.5 1.2 0.0', SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y);
n.pullNexposee(n, i, eY * (SKINHEIGHT_TITLE * SKINFONTSIZE_TITLE / conheight));
me.disconnectDialog = i;
-
+
i = NEW(XonoticQuitDialog);
i.configureDialog(i);
n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
me.initializeDialog(me, n);
me.disconnectDialogVisibility = 1;
- if(cvar_string("_cl_name") == cvar_defstring("_cl_name"))
+ if (me.ToSDialog.shouldShow())
+ {
+ me.dialogToShow = me.ToSDialog;
+ }
+ else if(me.firstRunDialog.shouldShow())
+ {
me.dialogToShow = me.firstRunDialog;
+ }
}
CLASS(MainWindow, ModalController)
METHOD(MainWindow, configureMainWindow, void(entity));
METHOD(MainWindow, draw, void(entity));
+ ATTRIB(MainWindow, ToSDialog, entity);
ATTRIB(MainWindow, firstRunDialog, entity);
ATTRIB(MainWindow, advancedDialog, entity);
ATTRIB(MainWindow, mutatorsDialog, entity);