6 | We've emailed you instructions for setting your password, if an account exists with the email you entered.
7 | You should receive them shortly.
8 |
9 |
10 | If you don't receive an email, please make sure you've entered the address you registered with,
11 | and check your spam folder.
12 |
12 | The resource or page you are attempting to access is associated with a
13 | puzzlehunt that is not yet started. Please refresh this page after the
14 | hunt has started.
15 |
20 | You must be participating in the current hunt to view this resource or
21 | page, and it does not appear you are on a team for this hunt. Please
22 | ensure you are signed in correctly and that you have properly added
23 | yourself to a team on the
24 | registration page.
25 |
30 | This resource or page is part of an ongoing puzzlehunt and is not yet
31 | unlocked for your team. Please either continue playing to unlock it or
32 | wait until the hunt is public.
33 |
35 | If you don't have an account with either Carnegie Mellon University or
36 | the University of Pittsburgh, you can
37 | create a Puzzlehunt Local Login account.
38 |
39 | (Again, this does not need to be done for CMU or Pitt students)
40 |
41 |
42 |
Forgot your password?
43 |
44 |
45 | If you are using a university account, please use their services to reset your password.
46 | If you are using a Puzzle Hunt CMU account, you can reset your password here.
47 |
18 | Each puzzle yields a solution (like a word or a phrase). You'll be combining answers to
19 | puzzles with a mechanic that will be explained more on the day of the hunt.
20 | Eventually players reach the endgame, a bonus round for those who
21 | complete the puzzles the fastest.
22 |
23 |
How do I register?
24 |
Register your team of {{curr_hunt.team_size|apnumber}} (or fewer if you want) here!
25 |
26 |
27 |
What should I bring?
28 |
29 |
30 |
A team of no more than {{curr_hunt.team_size|apnumber}} people. Humans only, please. Robots are discouraged; they mess up the sensors.
31 |
Laptops. All of our puzzles will be online.
32 |
Scissors. These will be helpful.
33 |
34 |
35 |
36 |
37 |
How long will it last?
38 |
The hunt is expected to run 8 hours. If there isn't a winner by 8 hours in (rare), we'll inform all teams to keep playing and continue until there's a winner.
39 |
40 |
Will there be food?
41 |
42 | Yes, there will be food, usually pizza. If you have dietary restrictions, please list them in the appropriate box when registering.
43 |
44 |
45 |
Is there anything else I should know?
46 |
47 |
48 |
There may be some running around campus required.
49 |
You CAN register a partial team and we'll do our best to try to match all of the partial teams on the day of.
50 |
Nothing on this and the registration page is a puzzle crucial for completing the hunt. No, really, this is not a puzzle.
51 |
52 |
53 |
54 |
Wait, I have more questions!
55 |
Email the HALP?! LINE ({% contact_email %}) with "Puzzle Hunt" somewhere in the subject line.
56 |
--------------------------------------------------------------------------------
/huntserver/static/huntserver/queue.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | var flashing = false,
3 | focused = true;
4 | var title = document.title;
5 |
6 | $('.sub_form').on('submit', formListener);
7 |
8 | window.addEventListener('focus', function() {
9 | focused = true;
10 | flashing = false;
11 | });
12 | window.addEventListener('blur', function() {
13 | focused = false;
14 | });
15 |
16 | /* flash the title if necessary */
17 | setInterval(function() {
18 | if (flashing && !focused) {
19 | if (document.title[0] == '[') {
20 | document.title = title;
21 | } else {
22 | document.title = '[' + title + '] - New Submissions';
23 | }
24 | } else {
25 | document.title = title;
26 | }
27 | }, 1000);
28 |
29 | var get_posts = function() {
30 | $.ajax({
31 | type: 'get',
32 | url: "/staff/queue/",
33 | data: {last_date: last_date, all: true, puzzle_id: puzzle_id, team_id: team_id},
34 | success: function (response) {
35 | var response = JSON.parse(response);
36 | messages = response.submission_list;
37 | if(messages.length > 0){
38 | for (var i = 0; i < messages.length; i++) {
39 | receiveMessage(messages[i]);
40 | };
41 | last_date = response.last_date;
42 | }
43 | },
44 | error: function (html) {
45 | console.log(html);
46 | }
47 | });
48 | }
49 | setInterval(get_posts, 3000);
50 |
51 | function formListener(e) {
52 | e.preventDefault();
53 | old_row = $(this).parent().parent();
54 | $.ajax({
55 | url : $(this).attr('action') || window.location.pathname,
56 | type: "POST",
57 | data: $(this).serialize(),
58 | success: function (response) {
59 | response = JSON.parse(response);
60 | old_row.replaceWith($(response.submission_list[0]));
61 | $('.sub_form').on('submit', formListener);
62 | },
63 | error: function (jXHR, textStatus, errorThrown) {
64 | console.log(jXHR);
65 | }
66 | });
67 | }
68 |
69 | function receiveMessage(submission) {
70 | submission = $(submission);
71 | pk = submission.data('id');
72 | if ($('tr[data-id=' + pk + ']').length == 0) {
73 | if(!submission.hasClass('correct')) {
74 | flashing = !focused;
75 | $('audio')[0].play();
76 | }
77 | submission.prependTo("#sub_table");
78 | if($('#sub_table tr').length >= 30){
79 | $('#sub_table tr:last').remove();
80 | }
81 | } else {
82 | $('tr[data-id=' + pk + ']').replaceWith(submission);
83 | }
84 | $('.sub_form').on('submit', formListener);
85 | }
86 |
87 | /* open a text box for submitting an email */
88 | $(document).delegate('.needs-response', 'click', function() {
89 | $(this).siblings('form').show();
90 | return false;
91 | });
92 | $(document).delegate('.canned-response', 'click', function() {
93 | $(this).siblings('form').submit();
94 | return false;
95 | });
96 | });
--------------------------------------------------------------------------------
/docs/basics.rst:
--------------------------------------------------------------------------------
1 | Basics
2 | ******
3 |
4 | Despite it's size, this project only has one main app named huntserver which
5 | does nearly everything. This page is meant to outline basic low level
6 | operational aspects and design choices of the server. This information is really
7 | only helpful for people looking to help develop or modify the application. If
8 | you're just using the application, you can skip all this. (models and views too)
9 |
10 | Design
11 | ------
12 | The design of this project is somewhat divided into two parts, the staff
13 | experience and the hunt participant experience.
14 |
15 | Staff is anyone that has the staff attribute set in the admin page. These users
16 | have access to the /staff/ area of the site; however, in order to access all
17 | functions and access the /admin/ area of the site, the user must also be a
18 | superuser as designated by Django.
19 |
20 | Dynamic Content
21 | ---------------
22 | Dynamic content is created by using a combination of the model-view controller
23 | and the default Django templating engine. Both are extensively documented on
24 | Django's website. Both models and views used in this project are documented by
25 | later pages.
26 |
27 | Static Content
28 | --------------
29 | Puzzles should not be checked into the Github repository. They should exist on
30 | some accessible online file source (we have used Dropboxin the past)
31 | and will be downloaded and converted when the admin choses to do so.
32 | Once downloaded, the puzzle files live in ``{PROJECT FOLDER}/media/puzzles/``
33 | and are named using the "puzzle id" field of the puzzle which is enforced to
34 | be unique to each puzzle.
35 |
36 | To protect users from being able to just go to
37 | ``/media/puzzles/{Puzzle_id}.pdf`` and get puzzles, the server comes included
38 | with a protected routing path utilizing X-Sendfile. The /protected/ URL will
39 | only allow a user to access puzzle files if they have unlocked the puzzle.
40 | To avoid hard-coding that path, you can use the variable
41 | "settings.PROTECTED_URL" after importing the project settings.
42 |
43 | It is a bit simplistic, but anything in the puzzles directory is permission
44 | guarded by the set of hexadecimal characters before the '-' or '.' of the
45 | filename. If the requesting user has access to the puzzle object with the
46 | corresponding puzzle_id, then they will have access to that file.
47 | You can use this to protect files other than just the puzzle PDFs and PNGs.
48 |
49 | You should protect your /media/puzzles URL by only allowing access to
50 | /media/puzzles/ from internal sources. The Apache configuration for this project
51 | includes protection like this already.
52 |
53 | Database
54 | --------
55 | As noted in setup, the default database for this project is a Postgres database.
56 | After setup, the database should never need to be modified by hand,
57 | additions or deletions should be done from the online admin GUI or if absolutely
58 | necessary, from the Django interactive shell.
59 | Modifications to the table structure should only be done by modifying models.py
60 | and using the automatically created migration files.
61 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/dlareau/puzzlehunt_server)
2 | [](https://coveralls.io/github/dlareau/puzzlehunt_server)
3 |
4 | # puzzlehunt_server [Archive]
5 | ## Note! This project has been deprecated in favor of [PuzzleSpring](https://github.com/dlareau/puzzlespring).
6 | Please consider using PuzzleSpring instead of this project for new setups. It is more flexible, easier to get started with, and will see regular updates. A migration script for those who have already deployed puzzlehunt_server will be be released alongside PuzzleSpring 1.0.
7 |
8 |
9 | ## Old Description
10 | A server for running puzzle hunts. This project is mainly used by Puzzlehunt CMU to run their puzzlehunt, but is generic enough to be used for nearly any puzzle hunt. Includes basic features such as per-puzzle pages, automatic answer response, teams, customizable unlocking structure, and admin pages to manange submissions, teams, as well as hunt progress. It also includes automatic team creation from registration, privacy settings for hunts, cool charts, a built in chat, and automatic file fetching and hosting.
11 |
12 | Documentation can be found at http://docs.puzzlehunt.club
13 |
14 | If you are interested in getting this running elsewhere, let me (dlareau@cmu.edu) know. I'd be happy to help anyone who wants to get this up and running for their needs, and get help get you over any gaps in setup documentation. I'd also recommend if possible waiting for version 4.1 which will make adapting this software to other hunts easier: https://github.com/dlareau/puzzlehunt_server/issues/121
15 |
16 | Please submit issues for any bugs reports or feature requests.
17 |
18 | ### Setup
19 | This project now uses docker-compose as it's main form of setup. You can use the following steps to get a sample server up and going
20 |
21 | 1. Install [docker/docker-compose.](https://docs.docker.com/compose/install/)
22 | 2. Clone this repository.
23 | 3. Make a copy of ```sample.env``` named ```.env``` (yes, it starts with a dot).
24 | 4. Edit the new ```.env``` file, filling in new values for the first block of uncommented lines. Other lines can be safely ignored as they only provide additional functionality.
25 | 5. Run ```docker-compose up``` (possibly prepending ```sudo``` if needed)
26 | 6. Once up, you'll need to run the following commands to collect all the static files (to be run any time you alter static files) and to load in an initial hunt to pacify some of the display logic (to be run only once) :
27 | ```
28 | docker-compose exec app python3 /code/manage.py collectstatic --noinput
29 | docker-compose exec app python3 /code/manage.py loaddata initial_hunt
30 | ```
31 | 7. You should now have the server running on a newly created VM, accessible via [http://localhost](http://localhost). The repository you cloned has been linked into the VM by docker, so any changes made to the repository on the host system should show up automatically. (A ```docker-compose restart``` may be needed for some changes to take effect)
32 |
--------------------------------------------------------------------------------
/huntserver/templates/hunt_example.html:
--------------------------------------------------------------------------------
1 | {% extends "hunt_base.html" %}
2 | {% load hunt_tags %}
3 |
4 |
28 |
29 | {% block title %}Puzzles!{% endblock title %}
30 |
31 | {% block content %}
32 |
49 | We are Puzzle Hunt CMU, a group of puzzle enthusiasts from Carnegie Mellon University. We work together to solve Puzzle Hunts such as the MIT mystery hunt, or any of the many tech company puzzle hunts (examples of such companies include Microsoft, APT and Palantir). We also write and host CMU's very own puzzle hunt once a semester, with the goal of providing a fun-filled experience to as many members of the community as possible.
50 |
51 |
What is a puzzle hunt?
52 |
53 | Very simply put, it's an event where people get together to solve carefully designed puzzles which somehow link together on a larger scale.
54 |
55 | A puzzle hunt is typically characterized by its structure. In addition to several normal puzzles, each round has a meta-puzzle, which requires teams to have solved most of the normal puzzles to even unlock, and often requires solvers to incorporate answers from that round's normal puzzles to make sense of.
56 |
57 | Our puzzle hunt's structure changes from semester to semester so as to provide new challenges for solvers.
58 |