<commit_before>import Civ5SavePropertyDefinitions from "./civ5saveproperties";

const repoUrl = "https://github.com/bmaupin/civ5save";

export default class Civ5Save {
  constructor(saveData) {
    this.saveData = new Civ5SaveDataView(saveData.buffer);
    this.verifyFileSignature();
    this.properties = this.getProperties();
    this.sectionOffsets = this.getSectionOffsets();
    this.verifySaveGameVersion();
  }

  // Use a static factory to instantiate the object since it relies on data that needs to be fetched asynchronously
  // https://stackoverflow.com/a/24686979/399105
  static async fromFile(saveFile) {
    let saveData = await Civ5Save.loadData(saveFile);
    return new Civ5Save(saveData);
  }

  static loadData(saveFile) {
    return new Promise(function (resolve, reject) {
      let reader = new FileReader();

      reader.onload = function () {
        // Use a DataView for the savegame data since the ArrayBuffer returned by reader.result can't be used to
        // manipulate the data. A typed array such as Int8Array wouldn't be ideal either since the data contains types
        // of variable lengths
        resolve(new DataView(reader.result));
      }
      reader.onerror = function () {
        reject(reader.error);
      }

      reader.readAsArrayBuffer(saveFile);
    });
  }

  verifyFileSignature() {
    if (this.saveData.getAsciiString(0, 4) !== "CIV5") {
      throw new Error("File signature does not match. Is this a Civ 5 savegame?");
    }
  }

  getProperties() {
    let properties = new Map();
    for (let propertyName in Civ5SavePropertyDefinitions) {
      let propertyDefinition = Civ5SavePropertyDefinitions[propertyName];
      switch (propertyDefinition.type) {
        case "int16":
          properties[propertyName] = (new Civ5SaveInt16Property(propertyDefinition, this.saveData));
          break;

        case "int32":
          properties[propertyName] = (new Civ5SaveInt32Property(propertyDefinition, this.saveData));
          break;

        case "skip":
          properties[propertyName] = (new Civ5SaveProperty(propertyDefinition, this.saveData));
          break;

        case "string":
          properties[propertyName] = (new Civ5SaveStringProperty(propertyDefinition, this.saveData));
          break;

        default: {
          throw new Error(`Property type ${propertyDefinition.type} not handled: ${propertyName}, ${propertyDefinition}`);
        }
      }
    }

    return properties;
  }

  getSectionOffsets() {
    const sectionDelimiter = [0x40, 0, 0, 0];

    let saveDataBytes = new Int8Array(this.saveData.buffer);
    let sectionOffsets = [];
    let section = {
      start: 0,
    };
    sectionOffsets.push(section);

    saveDataBytes.forEach((byte, byteOffset) => {
      if (areArraysEqual(saveDataBytes.slice(byteOffset, byteOffset + 4), sectionDelimiter)) {
        let section = {
          start: byteOffset,
        };
        sectionOffsets.push(section);
        sectionOffsets[sectionOffsets.length - 2].end = byteOffset - 1;
      }
    });

    return sectionOffsets;
  }

  verifySaveGameVersion() {
    if (this.saveGameVersion !== 8) {
      throw new Error(`Savegame version ${this.saveGameVersion} unsupported. Please file an issue at ${repoUrl}.`);
    }
  }

  getProperty(propertyName) {
    this.populatePropertyAttributes(propertyName);

    return this.properties[propertyName].value;
  }

  populatePropertyAttributes(propertyName) {
    this.populatePropertySection(propertyName);
    this.populatePropertyByteOffsetInSection(propertyName);
    this.populatePropertyByteOffset(propertyName);
    this.populatePropertyLength(propertyName);
  }

  populatePropertySection(propertyName) {
    let property = this.properties[propertyName];
    if (isNullOrUndefined(property.section)) {
      for (var build in property.sectionByBuild) {
        if (Number.parseInt(this.gameBuild) > Number.parseInt(build)) {
          property.section = property.sectionByBuild[build];
        }
      }
    }
  }

  populatePropertyByteOffsetInSection(propertyName) {
    let property = this.properties[propertyName];
    if (isNullOrUndefined(property.byteOffsetInSection)) {
      let previousPropertyName = property.previousProperty;
      let previousProperty = this.properties[previousPropertyName];
      this.populatePropertyAttributes(previousPropertyName);
      property.byteOffsetInSection = previousProperty.byteOffsetInSection + previousProperty.length;
    }
  }

  populatePropertyByteOffset(propertyName) {
    let property = this.properties[propertyName];
    if (isNullOrUndefined(property.byteOffset)) {
      property.byteOffset = this.sectionOffsets[property.section - 1].start + property.byteOffsetInSection;
    }
  }

  populatePropertyLength(propertyName) {
    let property = this.properties[propertyName];
    if (isNullOrUndefined(property.length)) {
      property.length = this.saveData.getStringLength(property.byteOffset) + 4;
    }
  }

  get saveGameVersion() {
    return this.getProperty("saveGameVersion");
  }

  get gameVersion() {
    return this.getProperty("gameVersion");
  }

  get gameBuild() {
    return this.getProperty("gameBuild");
  }

  get maxTurns() {
    return this.getProperty("maxTurns");
  }
}

// Subclassing DataView in babel requires https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
class Civ5SaveDataView extends DataView {
  getVariableLengthString(byteOffset) {
    let stringLength = this.getStringLength(byteOffset);
    return this.getAsciiString(byteOffset + 4, stringLength);
  }

  getStringLength(byteOffset) {
    return this.getInt32(byteOffset, true);
  }

  getAsciiString(byteOffset, byteLength) {
    let string = "";
    for (let byte = byteOffset; byte < byteOffset + byteLength; byte++) {
      string += String.fromCharCode(this.getInt8(byte));
    }
    return string;
  }
}

class Civ5SaveProperty {
  constructor(propertyDefinition, saveData) {
    this.byteOffset = propertyDefinition.byteOffset;
    this.byteOffsetInSection = propertyDefinition.byteOffsetInSection;
    this.length = propertyDefinition.length;
    this.previousProperty = propertyDefinition.previousProperty;
    this.saveData = saveData;
    this.section = propertyDefinition.section;
    this.sectionByBuild = propertyDefinition.sectionByBuild;
  }
}

class Civ5SaveInt16Property extends Civ5SaveProperty {
  get value() {
    return this.saveData.getInt16(this.byteOffset, true);
  }
}

class Civ5SaveInt32Property extends Civ5SaveProperty {
  get value() {
    return this.saveData.getInt32(this.byteOffset, true);
  }
}

class Civ5SaveStringProperty extends Civ5SaveProperty {
  get value() {
    return this.saveData.getVariableLengthString(this.byteOffset);
  }
}

// https://stackoverflow.com/a/22395463/399105
function areArraysEqual(array1, array2) {
  return (array1.length == array2.length) && array1.every(function(element, index) {
    return element === array2[index];
  });
}

// https://stackoverflow.com/a/416327/399105
function isNullOrUndefined(variable) {
  return typeof variable === "undefined" || variable === null;
}
<commit_msg>Move logic for calculating length to string property class<commit_after>import Civ5SavePropertyDefinitions from "./civ5saveproperties";

const repoUrl = "https://github.com/bmaupin/civ5save";

export default class Civ5Save {
  constructor(saveData) {
    this.saveData = new Civ5SaveDataView(saveData.buffer);
    this.verifyFileSignature();
    this.properties = this.getProperties();
    this.sectionOffsets = this.getSectionOffsets();
    this.verifySaveGameVersion();
  }

  // Use a static factory to instantiate the object since it relies on data that needs to be fetched asynchronously
  // https://stackoverflow.com/a/24686979/399105
  static async fromFile(saveFile) {
    let saveData = await Civ5Save.loadData(saveFile);
    return new Civ5Save(saveData);
  }

  static loadData(saveFile) {
    return new Promise(function (resolve, reject) {
      let reader = new FileReader();

      reader.onload = function () {
        // Use a DataView for the savegame data since the ArrayBuffer returned by reader.result can't be used to
        // manipulate the data. A typed array such as Int8Array wouldn't be ideal either since the data contains types
        // of variable lengths
        resolve(new DataView(reader.result));
      }
      reader.onerror = function () {
        reject(reader.error);
      }

      reader.readAsArrayBuffer(saveFile);
    });
  }

  verifyFileSignature() {
    if (this.saveData.getString(0, 4) !== "CIV5") {
      throw new Error("File signature does not match. Is this a Civ 5 savegame?");
    }
  }

  getProperties() {
    let properties = new Map();
    for (let propertyName in Civ5SavePropertyDefinitions) {
      let propertyDefinition = Civ5SavePropertyDefinitions[propertyName];
      switch (propertyDefinition.type) {
        case "int16":
          properties[propertyName] = (new Civ5SaveInt16Property(propertyDefinition, this.saveData));
          break;

        case "int32":
          properties[propertyName] = (new Civ5SaveInt32Property(propertyDefinition, this.saveData));
          break;

        case "skip":
          properties[propertyName] = (new Civ5SaveProperty(propertyDefinition, this.saveData));
          break;

        case "string":
          properties[propertyName] = (new Civ5SaveStringProperty(propertyDefinition, this.saveData));
          break;

        default: {
          throw new Error(`Property type ${propertyDefinition.type} not handled: ${propertyName}, ${propertyDefinition}`);
        }
      }
    }

    return properties;
  }

  getSectionOffsets() {
    const sectionDelimiter = [0x40, 0, 0, 0];

    let saveDataBytes = new Int8Array(this.saveData.buffer);
    let sectionOffsets = [];
    let section = {
      start: 0,
    };
    sectionOffsets.push(section);

    saveDataBytes.forEach((byte, byteOffset) => {
      if (areArraysEqual(saveDataBytes.slice(byteOffset, byteOffset + 4), sectionDelimiter)) {
        let section = {
          start: byteOffset,
        };
        sectionOffsets.push(section);
        sectionOffsets[sectionOffsets.length - 2].end = byteOffset - 1;
      }
    });

    return sectionOffsets;
  }

  verifySaveGameVersion() {
    if (this.saveGameVersion !== 8) {
      throw new Error(`Savegame version ${this.saveGameVersion} unsupported. Please file an issue at ${repoUrl}.`);
    }
  }

  getProperty(propertyName) {
    this.populatePropertyAttributes(propertyName);

    return this.properties[propertyName].value;
  }

  populatePropertyAttributes(propertyName) {
    this.populatePropertySection(propertyName);
    this.populatePropertyByteOffsetInSection(propertyName);
    this.populatePropertyByteOffset(propertyName);
  }

  populatePropertySection(propertyName) {
    let property = this.properties[propertyName];
    if (isNullOrUndefined(property.section)) {
      for (var build in property.sectionByBuild) {
        if (Number.parseInt(this.gameBuild) > Number.parseInt(build)) {
          property.section = property.sectionByBuild[build];
        }
      }
    }
  }

  populatePropertyByteOffsetInSection(propertyName) {
    let property = this.properties[propertyName];
    if (isNullOrUndefined(property.byteOffsetInSection)) {
      let previousPropertyName = property.previousProperty;
      let previousProperty = this.properties[previousPropertyName];
      this.populatePropertyAttributes(previousPropertyName);
      property.byteOffsetInSection = previousProperty.byteOffsetInSection + previousProperty.length;
    }
  }

  populatePropertyByteOffset(propertyName) {
    let property = this.properties[propertyName];
    if (isNullOrUndefined(property.byteOffset)) {
      property.byteOffset = this.sectionOffsets[property.section - 1].start + property.byteOffsetInSection;
    }
  }

  get saveGameVersion() {
    return this.getProperty("saveGameVersion");
  }

  get gameVersion() {
    return this.getProperty("gameVersion");
  }

  get gameBuild() {
    // return this.getProperty("gameBuild");

    let gameVersion = this.getProperty("gameBuild");
    // console.log(this.properties);
    return gameVersion;
  }

  get maxTurns() {
    // return this.getProperty("maxTurns");

    let gameVersion = this.getProperty("maxTurns");
    // console.log(this.properties);
    return gameVersion;
  }
}

// Subclassing DataView in babel requires https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
class Civ5SaveDataView extends DataView {
  getString(byteOffset, byteLength) {
    let string = "";
    for (let byte = byteOffset; byte < byteOffset + byteLength; byte++) {
      string += String.fromCharCode(this.getInt8(byte));
    }
    return string;
  }
}

class Civ5SaveProperty {
  constructor(propertyDefinition, saveData) {
    this.byteOffset = propertyDefinition.byteOffset;
    this.byteOffsetInSection = propertyDefinition.byteOffsetInSection;
    this._length = propertyDefinition.length;
    this.previousProperty = propertyDefinition.previousProperty;
    this.saveData = saveData;
    this.section = propertyDefinition.section;
    this.sectionByBuild = propertyDefinition.sectionByBuild;
  }

  get length() {
    return this._length;
  }
}

class Civ5SaveInt16Property extends Civ5SaveProperty {
  get value() {
    return this.saveData.getInt16(this.byteOffset, true);
  }
}

class Civ5SaveInt32Property extends Civ5SaveProperty {
  get value() {
    return this.saveData.getInt32(this.byteOffset, true);
  }
}

class Civ5SaveStringProperty extends Civ5SaveProperty {
  get length() {
    if (isNullOrUndefined(this._length)) {
      this._length = this.getStringLength(this.byteOffset) + 4;
    }
    return this._length;
  }

  get value() {
    return this.saveData.getString(this.byteOffset + 4, this.length - 4);
  }

  getStringLength(byteOffset) {
    return this.saveData.getInt32(byteOffset, true);
  }
}

// https://stackoverflow.com/a/22395463/399105
function areArraysEqual(array1, array2) {
  return (array1.length == array2.length) && array1.every(function(element, index) {
    return element === array2[index];
  });
}

// https://stackoverflow.com/a/416327/399105
function isNullOrUndefined(variable) {
  return typeof variable === "undefined" || variable === null;
}
<|endoftext|>


<commit_before>/*
Copyright (C) 2011 by Gregory Burlet, Alastair Porter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * Creates a new clef view
 *
 * @class View for the clef
 * @param {Toe.View.RenderEngine} renderEngine The rendering engine
 */
Toe.View.ClefView = function(renderEngine) {
    this.rendEng = renderEngine;

    this.drawing = null;
}

Toe.View.ClefView.prototype.constructor = Toe.View.ClefView;

Toe.View.ClefView.prototype.drawClef = function(clef) {
    if (!this.rendEng) {
        throw new Error("Clef: Invalid render context");
    }

    var staff = clef.staff;

    var svgKey = null;
    switch(clef.shape) {
        case "c":
            svgKey = "c_clef";
            break;
        case "f":
            svgKey = "f_clef";
            break;
    }

    var cGlyph = this.rendEng.getGlyph(svgKey);
    var glyphLeft = clef.zone.ulx + cGlyph.centre[0];
    var glyphTop = staff.zone.uly - clef.props.staffPos*staff.delta_y/2;
     if (clef.shape == "f") {
        // 0.34 is the relative position of the f clef glyph placement
        glyphTop += 0.34*cGlyph.centre[1];
    }

    var svgClef = cGlyph.clone().set({left: glyphLeft, top: glyphTop}); // offset centre

    this.drawing = this.rendEng.draw({fixed: [], modify: [svgClef]}, {selectable: clef.props.interact, eleRef: clef})[0];

    // update model
    $(clef).trigger("mUpdateBoundingBox", this.drawing);
}

/**
 * Renders the clef
 * @methodOf Toe.View.ClefView
 * @param {Toe.Model.Clef} clef Clef to render
 */
Toe.View.ClefView.prototype.renderClef = function(clef) {
    this.drawClef(clef);
}

Toe.View.ClefView.prototype.updateShape = function(clef) {
    if (!this.drawing) {
        throw new Error("Clef: update method called, but there exists no drawing to update.");
    }
    else {
        // remove the old drawing
        this.rendEng.canvas.remove(this.drawing);
    }

    this.drawClef(clef);

    // select the new drawing
    this.selectDrawing();

    this.rendEng.repaint();
}

Toe.View.ClefView.prototype.updateStaffPosition = function(clef) {
    if (!this.drawing) {
        throw new Error("Clef: update method called, but there exists no drawing to update.");
    }

    var glyphTop = clef.staff.zone.uly - clef.props.staffPos*clef.staff.delta_y/2;
    if (clef.shape == "f") {
        // 0.34 is the relative position of the f clef glyph placement
        glyphTop += 0.34*this.drawing.currentHeight/2;
    }

    this.drawing.top = glyphTop;

    this.rendEng.repaint();

    // update model
    $(clef).trigger("mUpdateBoundingBox", this.drawing);
}

Toe.View.ClefView.prototype.selectDrawing = function() {
    this.rendEng.canvas.setActiveObject(this.drawing);
}
<commit_msg>Fixed clef glyph resizing<commit_after>/*
Copyright (C) 2011 by Gregory Burlet, Alastair Porter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * Creates a new clef view
 *
 * @class View for the clef
 * @param {Toe.View.RenderEngine} renderEngine The rendering engine
 */
Toe.View.ClefView = function(renderEngine) {
    this.rendEng = renderEngine;

    this.drawing = null;
}

Toe.View.ClefView.prototype.constructor = Toe.View.ClefView;

Toe.View.ClefView.prototype.drawClef = function(clef) {
    if (!this.rendEng) {
        throw new Error("Clef: Invalid render context");
    }

    var staff = clef.staff;

    var svgKey = null;
    switch(clef.shape) {
        case "c":
            svgKey = "c_clef";
            break;
        case "f":
            svgKey = "f_clef";
            break;
    }

    var cGlyph = this.rendEng.getGlyph(svgKey);
    var glyphLeft = clef.zone.ulx + cGlyph.centre[0];
    var glyphTop = staff.zone.uly - clef.props.staffPos*staff.delta_y/2;
     if (clef.shape == "f") {
        // 0.34 is the relative position of the f clef glyph placement
        glyphTop += 0.34*cGlyph.centre[1];
    }

    var svgClef = cGlyph.clone().set({left: glyphLeft, top: glyphTop}); // offset centre

    this.drawing = this.rendEng.draw({fixed: [], modify: [svgClef]}, {selectable: clef.props.interact, group: true, eleRef: clef})[0];

    // update model
    $(clef).trigger("mUpdateBoundingBox", this.drawing);
}

/**
 * Renders the clef
 * @methodOf Toe.View.ClefView
 * @param {Toe.Model.Clef} clef Clef to render
 */
Toe.View.ClefView.prototype.renderClef = function(clef) {
    this.drawClef(clef);
}

Toe.View.ClefView.prototype.updateShape = function(clef) {
    if (!this.drawing) {
        throw new Error("Clef: update method called, but there exists no drawing to update.");
    }
    else {
        // remove the old drawing
        this.rendEng.canvas.remove(this.drawing);
    }

    this.drawClef(clef);

    // select the new drawing
    this.selectDrawing();

    this.rendEng.repaint();
}

Toe.View.ClefView.prototype.updateStaffPosition = function(clef) {
    if (!this.drawing) {
        throw new Error("Clef: update method called, but there exists no drawing to update.");
    }

    var glyphTop = clef.staff.zone.uly - clef.props.staffPos*clef.staff.delta_y/2;
    if (clef.shape == "f") {
        // 0.34 is the relative position of the f clef glyph placement
        glyphTop += 0.34*this.drawing.currentHeight/2;
    }

    this.drawing.top = glyphTop;

    this.rendEng.repaint();

    // update model
    $(clef).trigger("mUpdateBoundingBox", this.drawing);
}

Toe.View.ClefView.prototype.selectDrawing = function() {
    this.rendEng.canvas.setActiveObject(this.drawing);
}
<|endoftext|>


<commit_before>var vf = require('vf');
var boot = require('vsoft-boot');
var bodyParser = require('body-parser');

var app = vf();

app.use(vf.favicon());
app.use(bodyParser.urlencoded({ extended: true }));
boot(app, __dirname);

// console.log(app.datasources.db);

var ds = app.datasources.db,
    info = app.models.info;

app.post('/info', function(req, res){
    var obj = {};
    obj.Name = req.body.itb_ajax_form.name;
    obj.email = req.body.itb_ajax_form.email;
    obj.comment = req.body.itb_ajax_form.comments;
    info.create(obj, function(err) {
        if (err) return;
        res.redirect('/');
        // console.log('success');
    });
});

app.use(vf.urlNotFound());
app.use(vf.errorHandler());

app.start = function() {
    return app.listen(function() {
        app.emit('started');
        console.log('Server was running at %s', app.get('url'));
    });
};

if(require.main === module) {
    app.start();
}
<commit_msg>update<commit_after>var vf = require('vf');
var boot = require('vsoft-boot');
var bodyParser = require('body-parser');

var app = vf();

app.use(vf.favicon());
app.use(bodyParser.urlencoded({ extended: true }));
boot(app, __dirname);

// console.log(app.datasources.db);

var ds = app.datasources.db,
    info = app.models.info;

app.post('/info', function(req, res){
    var obj = {};
    obj.Name = req.body.itb_ajax_form.name;
    obj.email = req.body.itb_ajax_form.email;
    obj.comment = req.body.itb_ajax_form.comments;
    info.create(obj, function(err) {
        if (err) return;
        res.redirect('http://vsoft.vn');
        // console.log('success');
    });
});

app.use(vf.urlNotFound());
app.use(vf.errorHandler());

app.start = function() {
    return app.listen(function() {
        app.emit('started');
        console.log('Server was running at %s', app.get('url'));
    });
};

if(require.main === module) {
    app.start();
}
<|endoftext|>


<commit_before>"use strict";

var canvas = document.getElementById("canvas");

var Splat = require("splat-ecs");
require("./index.html");

// This is some webpack magic to ensure the dynamically required scripts are loaded

var splatSystemPath = "splat-ecs/lib/systems";
// WARNING: can't use splatSystemPath variable here, or webpack won't pick it up
var splatSystemRequire = require.context("splat-ecs/lib/systems", true, /\.js$/);

var localSystemPath = "./systems";
var localSystemRequire = require.context("./systems", true, /\.js$/);

var localScriptPath = "./scripts";
var localScriptRequire = require.context("./scripts", true, /\.js$/);

function generateManifest(files, folder) {
  return files.reduce(function(manifest, file) {
    var basename = file.substr(2);
    manifest[basename] = folder + "/" + basename;
    return manifest;
  }, {});
}

require.context("./fonts", true, /.*\.(eot|svg|ttf|woff2?)$/i);

var imageContext = require.context("./images", true, /\.(jpe?g|png|gif|svg)$/i);
var imageManifest = generateManifest(imageContext.keys(), "images");

var soundContext = require.context("./sounds", true, /\.(mp3|ogg|wav)$/i);
var soundManifest = generateManifest(soundContext.keys(), "sounds");

var localDataPath = "./data";
var localDataRequire = require.context("./data", true, /\.json$/);

var componentContext = require.context("./components", true, /\.js(on)?$/);
var componentManifest = generateComponentManifest(componentContext);

function generateComponentManifest(context) {
  var files = context.keys();
  return files.reduce(function(manifest, file) {
    var name = snakeToCamelCase(basename(file).substr(2));
    manifest[name] = context(file);
    return manifest;
  }, {});
}

function snakeToCamelCase(str) {
  return str.replace(/-([a-z])/g, function(g) { return g[1].toUpperCase(); });
}

function basename(path) {
  var pos = path.lastIndexOf(".");
  if (pos !== -1) {
    return path.substring(0, pos);
  }
  return path;
}

function customRequire(path) {
  if (path.indexOf(splatSystemPath) === 0) {
    var splatName = "./" + path.substr(splatSystemPath.length + 1) + ".js";
    return splatSystemRequire(splatName);
  }
  if (path.indexOf(localSystemPath) === 0) {
    var localName = "./" + path.substr(localSystemPath.length + 1) + ".js";
    return localSystemRequire(localName);
  }
  if (path.indexOf(localScriptPath) === 0) {
    var scriptName = "./" + path.substr(localScriptPath.length + 1) + ".js";
    return localScriptRequire(scriptName);
  }
  if (path === "./data/components") {
    return componentManifest;
  }
  if (path === "./data/images") {
    return imageManifest;
  }
  if (path === "./data/sounds") {
    return soundManifest;
  }
  if (path.indexOf(localDataPath) === 0) {
    var dataName = "./" + path.substr(localDataPath.length + 1) + ".json";
    return localDataRequire(dataName);
  }
  console.error("Unable to load module: \"", path, "\"");
  return undefined;
}

window.game = new Splat.Game(canvas, customRequire);
window.game.start();
<commit_msg>Make component manifest handle names with numbers<commit_after>"use strict";

var canvas = document.getElementById("canvas");

var Splat = require("splat-ecs");
require("./index.html");

// This is some webpack magic to ensure the dynamically required scripts are loaded

var splatSystemPath = "splat-ecs/lib/systems";
// WARNING: can't use splatSystemPath variable here, or webpack won't pick it up
var splatSystemRequire = require.context("splat-ecs/lib/systems", true, /\.js$/);

var localSystemPath = "./systems";
var localSystemRequire = require.context("./systems", true, /\.js$/);

var localScriptPath = "./scripts";
var localScriptRequire = require.context("./scripts", true, /\.js$/);

function generateManifest(files, folder) {
  return files.reduce(function(manifest, file) {
    var basename = file.substr(2);
    manifest[basename] = folder + "/" + basename;
    return manifest;
  }, {});
}

require.context("./fonts", true, /.*\.(eot|svg|ttf|woff2?)$/i);

var imageContext = require.context("./images", true, /\.(jpe?g|png|gif|svg)$/i);
var imageManifest = generateManifest(imageContext.keys(), "images");

var soundContext = require.context("./sounds", true, /\.(mp3|ogg|wav)$/i);
var soundManifest = generateManifest(soundContext.keys(), "sounds");

var localDataPath = "./data";
var localDataRequire = require.context("./data", true, /\.json$/);

var componentContext = require.context("./components", true, /\.js(on)?$/);
var componentManifest = generateComponentManifest(componentContext);

function generateComponentManifest(context) {
  var files = context.keys();
  return files.reduce(function(manifest, file) {
    var name = snakeToCamelCase(basename(file).substr(2));
    manifest[name] = context(file);
    return manifest;
  }, {});
}

function snakeToCamelCase(str) {
  return str.replace(/-([a-z0-9])/g, function(g) { return g[1].toUpperCase(); });
}

function basename(path) {
  var pos = path.lastIndexOf(".");
  if (pos !== -1) {
    return path.substring(0, pos);
  }
  return path;
}

function customRequire(path) {
  if (path.indexOf(splatSystemPath) === 0) {
    var splatName = "./" + path.substr(splatSystemPath.length + 1) + ".js";
    return splatSystemRequire(splatName);
  }
  if (path.indexOf(localSystemPath) === 0) {
    var localName = "./" + path.substr(localSystemPath.length + 1) + ".js";
    return localSystemRequire(localName);
  }
  if (path.indexOf(localScriptPath) === 0) {
    var scriptName = "./" + path.substr(localScriptPath.length + 1) + ".js";
    return localScriptRequire(scriptName);
  }
  if (path === "./data/components") {
    return componentManifest;
  }
  if (path === "./data/images") {
    return imageManifest;
  }
  if (path === "./data/sounds") {
    return soundManifest;
  }
  if (path.indexOf(localDataPath) === 0) {
    var dataName = "./" + path.substr(localDataPath.length + 1) + ".json";
    return localDataRequire(dataName);
  }
  console.error("Unable to load module: \"", path, "\"");
  return undefined;
}

window.game = new Splat.Game(canvas, customRequire);
window.game.start();
<|endoftext|>


<commit_before>/**
 * @module Lyria
 */
define('lyria/game', ['extend', 'lyria/viewport', 'lyria/scene/director', 'lyria/preloader', 'lyria/loop'], function(extend, Viewport, Director, Preloader, Loop) {'use strict';

  /**
   * Game class which has a viewport, scene director and preloader by
   * default.
   *
   * @class Game
   */
  return (function() {

    /**
     * @constructor
     */
    var Game = function(options) {
      var self = this;

      options = extend(options, {
        startLoop: true
      });

      /**
       * @property viewport
       * @type {Viewport}
       */
      // Set up a viewport
      this.viewport = new Viewport();

      /**
       * @property director
       * @type {Director}
       */
      // Add a scene director
      this.director = new Director(this.viewport);

      /**
       * @property preloader
       * @type {Preloader}
       */
      // Add a preloader
      this.preloader = new Preloader();

      // Bind the scene director to the preloader reference
      this.preloader.sceneDirector = this.director;

      // Add an update task to the loop with updates the scene director on each
      // frame
      Game.Loop.on('update', function(dt) {
        self.director.trigger('update', dt);
      });

      // Run game loop (if it should start by default)
      // In most cases, you'll need the loop (animation/physics/etc.)
      // In a pure event-based game - like a turn-based-strategy game -
      // you might want turn startLoop off
      if (options.startLoop) {
        Game.Loop.run();
      }
    };

    /**
     * @property Loop
     * @static
     * @type {Loop}
     */
    // Store the reference to the Lyria Loop at the Game object
    Game.Loop = Loop;

    return Game;

  })();

}); <commit_msg>Added pausing and resuming to the Game object, linked it to jquery focus/blur<commit_after>/**
 * @module Lyria
 */
define('lyria/game', ['extend', 'eventmap', 'mixin', 'jquery', 'lyria/viewport', 'lyria/scene/director', 'lyria/preloader', 'lyria/loop'], function(extend, EventMap, mixin, $, Viewport, Director, Preloader, Loop) {'use strict';

  /**
   * Game class which has a viewport, scene director and preloader by
   * default.
   *
   * @class Game
   */
  return (function() {

    /**
     * @constructor
     */
    var Game = function(options) {
      var self = this;

      options = extend(options, {
        startLoop: true
      });

      mixin(Game.prototype, new EventMap());

      /**
       * @property viewport
       * @type {Viewport}
       */
      // Set up a viewport
      this.viewport = new Viewport();

      /**
       * @property director
       * @type {Director}
       */
      // Add a scene director
      this.director = new Director(this.viewport);

      /**
       * @property preloader
       * @type {Preloader}
       */
      // Add a preloader
      this.preloader = new Preloader();

      // Bind the scene director to the preloader reference
      this.preloader.sceneDirector = this.director;

      this.paused = false;

      // Add an update task to the loop with updates the scene director on each
      // frame
      Game.Loop.on('update', function(dt) {
        self.director.trigger('update', dt);
      });

      // Run game loop (if it should start by default)
      // In most cases, you'll need the loop (animation/physics/etc.)
      // In a pure event-based game - like a turn-based-strategy game -
      // you might want turn startLoop off
      if (options.startLoop) {
        Game.Loop.run();
      }

      $(document).ready(function() {
        $(window).blur(self.pause);
        $(window).focus(self.resume);
      });
    };

    Game.prototype.pause = function() {
      this.paused = true;
      this.trigger('pause');
    };

    Game.prototype.resume = function() {
      this.paused = false;
      this.trigger('resume');
    };

    /**
     * @property Loop
     * @static
     * @type {Loop}
     */
    // Store the reference to the Lyria Loop at the Game object
    Game.Loop = Loop;

    return Game;

  })();

}); <|endoftext|>


<commit_before>/*
**  server.js -- platform-independent server startup script
**  Copyright (c) 2013 Ralf S. Engelschall <rse@engelschall.com>
*/

/*  program identification  */
var app = {
    name: "Server",
    vers: "0.0.0",
    date: "2013-01-01",
    logger: null
};

/*  determine path to server base directory  */
var basedir = __dirname;

/*  load required libraries (1/3)  */
var fs       = require("fs");
var path     = require("path");

/*  determine path to Node library directory  */
var libdir = path.resolve(path.join(basedir, "/lib/node_modules/"));
module.paths.unshift(libdir);
libdir = path.resolve(path.join(basedir, "/lib/local/"));
module.paths.unshift(libdir);

/*  load required libraries (2/3)  */
var ini      = require("node-ini");
var util     = require("util")
var dashdash = require("dashdash");

/*  default command-line value loading  */
var argv = [];
var config = ini.parseSync(path.join(basedir, "/server.ini"));
if (typeof config.server !== "undefined") {
    for (var name in config.server) {
        if (config.server.hasOwnProperty(name)) {
            if (typeof config.server[name] === "string") {
                argv.push("--" + name);
                argv.push(config.server[name]);
            }
            else if (config.server[name] instanceof Array) {
                for (var i = 0; i < config.server[name].length; i++) {
                    argv.push("--" + name);
                    argv.push(config.server[name][i]);
                }
            }
        }
    }
}
for (var i = 2; i < process.argv.length; i++)
    argv.push(process.argv[i]);

/*  die the reasonable way  */
var die = function (msg) {
    console.error("server: ERROR: %s", msg)
    process.exit(1)
};

/*  command-line argument parsing  */
var options = [
    {   name: "version", type: "bool", default: false,
        help: "Print tool version and exit." },
    {   names: [ "help", "h" ], type: "bool", default: false,
        help: "Print this help and exit." },
    {   names: [ "addr", "a" ], type: "string", default: "127.0.0.1",
        help: "IP address to listen", helpArg: "ADDRESS" },
    {   names: [ "port", "p" ], type: "integer", default: 8080,
        help: "TCP port to listen", helpArg: "PORT" },
    {   names: [ "backlog", "b" ], type: "integer", default: 511,
        help: "TCP socket connection backlog", helpArg: "CONNECTIONS" },
    {   names: [ "componentjs" , "cjs" ], type: "string", default: ".*\/component.js",
        help: "Regex matching the url of the ComponentJS file", helpArg: "REGEX" },
    {   names: [ "components", "cmps" ], type: "string", default: ".*/app/.*",
        help: "Regex matching the urls of the components files of the SPA", helpArg: "REGEX" },
    {   names: [ "app", "A" ], type: "arrayOfString", default: "",
        help: "application to load", helpArg: "APP" }
]
var parser = dashdash.createParser({
    options: options,
    interspersed: false
})
try {
    var opts = parser.parse(argv)
} catch (e) {
    die(e.message)
}
if (opts.help) {
    var help = parser.help().trimRight()
    console.log(
        "server: USAGE: server [options] [arguments]\n" +
        "options:\n" +
        help
    )
    process.exit(0)
}
else if (opts.version) {
    console.log(util.format("%s %s (%s)", app.name, app.vers, app.date))
    process.exit(0)
}
// console.log("opts:", opts)
// console.log("args:", opts._args)

/*  load required libraries (3/3)  */
var path            = require("path");
var util            = require("util");
var cors            = require("cors");
var express         = require("express");
var express_io      = require("express.io");
var express_winston = require("express-winston");
var winston         = require("winston");

/*  create a server logger  */
var loggerTransport = new winston.transports.File({
    filename: "server.log",
    handleExceptions: true,
    maxsize: 1024*1024,
    maxFiles: 10,
    json: false,
    colorize: false
});
app.logger = new (winston.Logger)({
    transports: [ loggerTransport ]
});
app.logger.log("info", "starting %s %s (%s)", app.name, app.vers, app.date);
process.on("uncaughtException", function (error) {
    app.logger.log("error", error);
    console.log("server: ERROR: " + error);
});

/*  establish a root server  */
var srv = express_io();
srv.http().io();
app.srv = srv;

/*  adjust server identification  */
srv.enable("trust proxy");
srv.disable("x-powered-by");
srv.use(function (req, res, next) {
    res.setHeader("Server", util.format("%s %s (%s)", app.name, app.vers, app.date));
    next();
});

/*  allow to be used behind a reverse proxy  */
srv.enable("trust proxy");

/*  support CORS  */
srv.use(cors(function (req, cb) {
    var options = { origin: false, credentials: true };
    if (typeof req.header("Origin") === "string")
        options.origin = true;
    cb(null, options);
}));

/*  access logging  */
srv.use(express_winston.logger({
    transports: [
        new winston.transports.File({
            filename: "server.access.log",
            maxsize: 1024*1024,
            maxFiles: 10,
            json: false,
            colorize: false
        })
    ]
}));

/*  make an Express server from custom JavaScript code  */
var mkAppJS = function (filename) {
    var mod;
    try        { mod = require(filename); }
    catch (ex) { die("failed to load JavaScript module \"" + filename + "\": " + ex.message); }
    if (typeof mod.setup !== "function")
        die("JavaScript module does not export \"setup\" function: " + filename);
    var srv = mod.setup(app);
    return srv;
};

/*  make an Express server as standard directory listing  */
var mkAppDir = function (dirname) {
    var srv = express();
    srv.disable("x-powered-by");
    srv.use(express.favicon(dirname + "/favicon.ico", { maxAge: 24*60*60*1000 }));
    srv.use(express.compress());
    srv.use(express.responseTime());
    srv.use(express.static(dirname, { maxAge: 1*60*60*1000 }));
    return srv;
};

/*  iterate over all configured servers  */
if (typeof opts.app === "undefined")
    die("no application(s) defined");
for (var i = 0; i < opts.app.length; i++) {
    /*  parse application specification  */
    var m = (opts.app[i] + "").match(/^(.+):(.+)$/);
    if (m === null)
        die("invalid app specification (has to be \"<url-prefix>:<file-or-dir-path>\")");
    var url = m[1];
    var src = m[2];

    /*  sanity check parameters  */
    if (!url.match(/^\//))
        die("invalid URL prefix (has to start with a slash)");
    if (!fs.existsSync(src))
        die("invalid app source: \"" + src + "\"  (has to be either JavaScript file or directory)");

    /*  determine type of Express application  */
    var stats = fs.statSync(src);
    var subsrv;
    if (stats.isFile()) {
        app.logger.log("info", "deploying custom app: url=%s src=%s", url, src);
        subsrv = mkAppJS(src);
    }
    else if (stats.isDirectory()) {
        var index = src + "/root.js";
        if (fs.existsSync(index) && fs.statSync(index).isFile()) {
            app.logger.log("info", "deploying custom app: url=%s src=%s", url, index);
            subsrv = mkAppJS(index);
        }
        else {
            app.logger.log("info", "deploying directory-index: url=%s src=%s", url, src);
            subsrv = mkAppDir(src);
        }
    }

    /*  configure as sub-server  */
    srv.use(url, subsrv);
}

/*  configure a fallback middleware  */
srv.use(function(req, res, next) {
    res.send(404, "Resource Not Found");
});

/*  error logging  */
srv.use(express_winston.errorLogger({
    level: "info",
    transports: [ loggerTransport ]
}));

/*  error logging  */
srv.use(express.errorHandler({ dumpExceptions: false, showStack: false }));

var hps = require("http-proxy-simple");

var myProxy = hps.createProxyServer({
    proxyHost: "127.0.0.1",
    proxyPort: 8129
});

myProxy.on("error", function (error, locationInfo) {
   console.log("Location: " + locationInfo);
   console.log("Error: " + error.stack);
});

var cjsFile = new RegExp(opts.componentjs)
var cmpFiles = new RegExp(opts.components)

myProxy.on("interceptResponseContent", function (clientResponse, responseBody, callback) {
    console.log('interceptResponseContent: ' + clientResponse.req.path)
    if (clientResponse.req.path.match(cjsFile) !== null) {
        var buffer = new Buffer(responseBody, 'utf8')
        var appended = new Buffer('alert("Pommes");', 'utf8')
        var finalBuffer = new Buffer(buffer.length + appended.length)

        buffer.copy(finalBuffer)
        appended.copy(finalBuffer, buffer.length)

        responseBody = finalBuffer.toString('utf8')
        var length = finalBuffer.length
        /*  Make sure the file is never loaded from cache  */
        clientResponse.statusCode = 200
        clientResponse.headers["content-length"] = length
        clientResponse.headers["content-type"] = 'application/javascript'
        clientResponse.headers["accept-ranges"] = 'bytes'
        clientResponse.headers["x-cache"] = clientResponse.headers["x-cache"].replace('HIT', 'MISS')
        clientResponse.headers["x-cache-lookup"] = clientResponse.headers["x-cache-lookup"].replace('HIT', 'MISS')
        console.log('Discovered CJS file')
    } else if (clientResponse.req.path.match(cmpFiles) !== null) {
        console.log('Discovered component file')
    }
    callback(clientResponse, responseBody);
});

/*  start the listening on the root server  */
srv.listen(opts.port, opts.addr, opts.backlog, function () {
    app.logger.log("info", "listening on http://%s:%d", opts.addr, opts.port);
});
<commit_msg>Added fixme<commit_after>/*
**  server.js -- platform-independent server startup script
**  Copyright (c) 2013 Ralf S. Engelschall <rse@engelschall.com>
*/

/*  program identification  */
var app = {
    name: "Server",
    vers: "0.0.0",
    date: "2013-01-01",
    logger: null
};

/*  determine path to server base directory  */
var basedir = __dirname;

/*  load required libraries (1/3)  */
var fs       = require("fs");
var path     = require("path");

/*  determine path to Node library directory  */
var libdir = path.resolve(path.join(basedir, "/lib/node_modules/"));
module.paths.unshift(libdir);
libdir = path.resolve(path.join(basedir, "/lib/local/"));
module.paths.unshift(libdir);

/*  load required libraries (2/3)  */
var ini      = require("node-ini");
var util     = require("util")
var dashdash = require("dashdash");

/*  default command-line value loading  */
var argv = [];
var config = ini.parseSync(path.join(basedir, "/server.ini"));
if (typeof config.server !== "undefined") {
    for (var name in config.server) {
        if (config.server.hasOwnProperty(name)) {
            if (typeof config.server[name] === "string") {
                argv.push("--" + name);
                argv.push(config.server[name]);
            }
            else if (config.server[name] instanceof Array) {
                for (var i = 0; i < config.server[name].length; i++) {
                    argv.push("--" + name);
                    argv.push(config.server[name][i]);
                }
            }
        }
    }
}
for (var i = 2; i < process.argv.length; i++)
    argv.push(process.argv[i]);

/*  die the reasonable way  */
var die = function (msg) {
    console.error("server: ERROR: %s", msg)
    process.exit(1)
};

/*  command-line argument parsing  */
var options = [
    {   name: "version", type: "bool", default: false,
        help: "Print tool version and exit." },
    {   names: [ "help", "h" ], type: "bool", default: false,
        help: "Print this help and exit." },
    {   names: [ "addr", "a" ], type: "string", default: "127.0.0.1",
        help: "IP address to listen", helpArg: "ADDRESS" },
    {   names: [ "port", "p" ], type: "integer", default: 8080,
        help: "TCP port to listen", helpArg: "PORT" },
    {   names: [ "backlog", "b" ], type: "integer", default: 511,
        help: "TCP socket connection backlog", helpArg: "CONNECTIONS" },
    {   names: [ "componentjs" , "cjs" ], type: "string", default: ".*\/component.js",
        help: "Regex matching the url of the ComponentJS file", helpArg: "REGEX" },
    {   names: [ "components", "cmps" ], type: "string", default: ".*/app/.*",
        help: "Regex matching the urls of the components files of the SPA", helpArg: "REGEX" },
    {   names: [ "app", "A" ], type: "arrayOfString", default: "",
        help: "application to load", helpArg: "APP" }
]
var parser = dashdash.createParser({
    options: options,
    interspersed: false
})
try {
    var opts = parser.parse(argv)
} catch (e) {
    die(e.message)
}
if (opts.help) {
    var help = parser.help().trimRight()
    console.log(
        "server: USAGE: server [options] [arguments]\n" +
        "options:\n" +
        help
    )
    process.exit(0)
}
else if (opts.version) {
    console.log(util.format("%s %s (%s)", app.name, app.vers, app.date))
    process.exit(0)
}
// console.log("opts:", opts)
// console.log("args:", opts._args)

/*  load required libraries (3/3)  */
var path            = require("path");
var util            = require("util");
var cors            = require("cors");
var express         = require("express");
var express_io      = require("express.io");
var express_winston = require("express-winston");
var winston         = require("winston");

/*  create a server logger  */
var loggerTransport = new winston.transports.File({
    filename: "server.log",
    handleExceptions: true,
    maxsize: 1024*1024,
    maxFiles: 10,
    json: false,
    colorize: false
});
app.logger = new (winston.Logger)({
    transports: [ loggerTransport ]
});
app.logger.log("info", "starting %s %s (%s)", app.name, app.vers, app.date);
process.on("uncaughtException", function (error) {
    app.logger.log("error", error);
    console.log("server: ERROR: " + error);
});

/*  establish a root server  */
var srv = express_io();
srv.http().io();
app.srv = srv;

/*  adjust server identification  */
srv.enable("trust proxy");
srv.disable("x-powered-by");
srv.use(function (req, res, next) {
    res.setHeader("Server", util.format("%s %s (%s)", app.name, app.vers, app.date));
    next();
});

/*  allow to be used behind a reverse proxy  */
srv.enable("trust proxy");

/*  support CORS  */
srv.use(cors(function (req, cb) {
    var options = { origin: false, credentials: true };
    if (typeof req.header("Origin") === "string")
        options.origin = true;
    cb(null, options);
}));

/*  access logging  */
srv.use(express_winston.logger({
    transports: [
        new winston.transports.File({
            filename: "server.access.log",
            maxsize: 1024*1024,
            maxFiles: 10,
            json: false,
            colorize: false
        })
    ]
}));

/*  make an Express server from custom JavaScript code  */
var mkAppJS = function (filename) {
    var mod;
    try        { mod = require(filename); }
    catch (ex) { die("failed to load JavaScript module \"" + filename + "\": " + ex.message); }
    if (typeof mod.setup !== "function")
        die("JavaScript module does not export \"setup\" function: " + filename);
    var srv = mod.setup(app);
    return srv;
};

/*  make an Express server as standard directory listing  */
var mkAppDir = function (dirname) {
    var srv = express();
    srv.disable("x-powered-by");
    srv.use(express.favicon(dirname + "/favicon.ico", { maxAge: 24*60*60*1000 }));
    srv.use(express.compress());
    srv.use(express.responseTime());
    srv.use(express.static(dirname, { maxAge: 1*60*60*1000 }));
    return srv;
};

/*  iterate over all configured servers  */
if (typeof opts.app === "undefined")
    die("no application(s) defined");
for (var i = 0; i < opts.app.length; i++) {
    /*  parse application specification  */
    var m = (opts.app[i] + "").match(/^(.+):(.+)$/);
    if (m === null)
        die("invalid app specification (has to be \"<url-prefix>:<file-or-dir-path>\")");
    var url = m[1];
    var src = m[2];

    /*  sanity check parameters  */
    if (!url.match(/^\//))
        die("invalid URL prefix (has to start with a slash)");
    if (!fs.existsSync(src))
        die("invalid app source: \"" + src + "\"  (has to be either JavaScript file or directory)");

    /*  determine type of Express application  */
    var stats = fs.statSync(src);
    var subsrv;
    if (stats.isFile()) {
        app.logger.log("info", "deploying custom app: url=%s src=%s", url, src);
        subsrv = mkAppJS(src);
    }
    else if (stats.isDirectory()) {
        var index = src + "/root.js";
        if (fs.existsSync(index) && fs.statSync(index).isFile()) {
            app.logger.log("info", "deploying custom app: url=%s src=%s", url, index);
            subsrv = mkAppJS(index);
        }
        else {
            app.logger.log("info", "deploying directory-index: url=%s src=%s", url, src);
            subsrv = mkAppDir(src);
        }
    }

    /*  configure as sub-server  */
    srv.use(url, subsrv);
}

/*  configure a fallback middleware  */
srv.use(function(req, res, next) {
    res.send(404, "Resource Not Found");
});

/*  error logging  */
srv.use(express_winston.errorLogger({
    level: "info",
    transports: [ loggerTransport ]
}));

/*  error logging  */
srv.use(express.errorHandler({ dumpExceptions: false, showStack: false }));

var hps = require("http-proxy-simple");

var myProxy = hps.createProxyServer({
    proxyHost: "127.0.0.1",
    proxyPort: 8129
});

myProxy.on("error", function (error, locationInfo) {
   console.log("Location: " + locationInfo);
   console.log("Error: " + error.stack);
});

var cjsFile = new RegExp(opts.componentjs)
var cmpFiles = new RegExp(opts.components)

myProxy.on("interceptResponseContent", function (clientResponse, responseBody, callback) {
    console.log('interceptResponseContent: ' + clientResponse.req.path)
    if (clientResponse.req.path.match(cjsFile) !== null) {
        var buffer = new Buffer(responseBody, 'utf8')
        var appended = new Buffer('alert("Pommes");', 'utf8')
        var finalBuffer = new Buffer(buffer.length + appended.length)

        buffer.copy(finalBuffer)
        appended.copy(finalBuffer, buffer.length)

        responseBody = finalBuffer.toString('utf8')
        var length = finalBuffer.length
        /*  Make sure the file is never loaded from cache  */
        clientResponse.statusCode = 200
        clientResponse.headers["content-length"] = length
        clientResponse.headers["content-type"] = 'application/javascript'
        clientResponse.headers["accept-ranges"] = 'bytes'
        //FIXME only replace HIT with MISS, when present
        //clientResponse.headers["x-cache"] = clientResponse.headers["x-cache"].replace('HIT', 'MISS')
        //clientResponse.headers["x-cache-lookup"] = clientResponse.headers["x-cache-lookup"].replace('HIT', 'MISS')
        console.log('Discovered CJS file')
    } else if (clientResponse.req.path.match(cmpFiles) !== null) {
        console.log('Discovered component file')
    }
    callback(clientResponse, responseBody);
});

/*  start the listening on the root server  */
srv.listen(opts.port, opts.addr, opts.backlog, function () {
    app.logger.log("info", "listening on http://%s:%d", opts.addr, opts.port);
});
<|endoftext|>


<commit_before>Lettris.Game = function (game) {
};

Lettris.Game.prototype = {
    create: function (game) {

	game.stage.disableVisibilityChange = true;

	this.stars = this.game.add.tileSprite(0, 0,
					      game.width, game.height,
					      'sprites', 'background');

	// Physics stuff
	game.physics.startSystem(Phaser.Physics.P2JS);
	game.physics.p2.setBoundsToWorld(true, true, false, true)
	game.physics.p2.gravity.y = 300;
	game.physics.p2.restitution = 0.05

	game.world.setBounds(0, 0, game.width, game.height-160);

	this.gameData = {score: 0,
			 karma: 0,
			 tiles_droped: 0,
			 tiles_cleared: 0,
			 best_word : {score: 0, word: ""}}

	this.boxes = game.add.group();

	this.gui = new GUI(game, this.gameData)
	this.bag = new Bag(game, this.boxes)

	this.fill_bottom(2)

	// Start box-droping loop
	this.spawn_box()
    },

    fill_bottom: function( layers ) {
	var boxSize = 80 // ugly
	var max_col = Math.floor(this.game.width / boxSize)
	for (row = 0; row < layers; row++) {
	    for (col = 0; col < max_col; col++) {
		var box = this.bag.placeBox(boxSize/2+(col*boxSize),
					    600-(boxSize*row))
		box.clicked.add(this.gui.box_clicked, this.gui)
	    }
	}
    },

    spawn_box: function () {
	// check if any box is stuck above screen => game over
	this.boxes.forEach(function(box) {
	    if( box.y < -box.width/2){
		this.state.start('GameOver', true, false, this.gameData);
		return;
	    }
	}, this);

	var box = this.bag.dropBox(this.gameData.karma)
	box.clicked.add(this.gui.box_clicked, this.gui)

	if(this.gameData.karma > 10)
	    this.gameData.karma = 10
	if(this.gameData.karma > 0)
	    this.gameData.karma /= 1.5

	this.gameData.tiles_droped++

	var spawnTime = this.spawn_time(this.gameData.tiles_cleared)
	this.game.time.events.add(spawnTime,
				  this.spawn_box,
				  this);
    },

    spawn_time: function(tiles){
	var min_speed = 0.8
	var start_speed = 4.0
	this.speed = min_speed +
	    ((start_speed - min_speed) *
	     Math.pow(1, Math.trunc(tiles/10)))
	return this.speed * Phaser.Timer.SECOND
    },
    update: function(){
	this.stars.tilePosition.y += 2.5 / this.speed;
    }
};
<commit_msg>Fix speed-bug<commit_after>Lettris.Game = function (game) {
};

Lettris.Game.prototype = {
    create: function (game) {

	game.stage.disableVisibilityChange = true;

	this.stars = this.game.add.tileSprite(0, 0,
					      game.width, game.height,
					      'sprites', 'background');

	// Physics stuff
	game.physics.startSystem(Phaser.Physics.P2JS);
	game.physics.p2.setBoundsToWorld(true, true, false, true)
	game.physics.p2.gravity.y = 300;
	game.physics.p2.restitution = 0.05

	game.world.setBounds(0, 0, game.width, game.height-160);

	this.gameData = {score: 0,
			 karma: 0,
			 tiles_droped: 0,
			 tiles_cleared: 0,
			 best_word : {score: 0, word: ""}}

	this.boxes = game.add.group();

	this.gui = new GUI(game, this.gameData)
	this.bag = new Bag(game, this.boxes)

	this.fill_bottom(2)

	// Start box-droping loop
	this.spawn_box()
    },

    fill_bottom: function( layers ) {
	var boxSize = 80 // ugly
	var max_col = Math.floor(this.game.width / boxSize)
	for (row = 0; row < layers; row++) {
	    for (col = 0; col < max_col; col++) {
		var box = this.bag.placeBox(boxSize/2+(col*boxSize),
					    600-(boxSize*row))
		box.clicked.add(this.gui.box_clicked, this.gui)
	    }
	}
    },

    spawn_box: function () {
	// check if any box is stuck above screen => game over
	this.boxes.forEach(function(box) {
	    if( box.y < -box.width/2){
		this.state.start('GameOver', true, false, this.gameData);
		return;
	    }
	}, this);

	var box = this.bag.dropBox(this.gameData.karma)
	box.clicked.add(this.gui.box_clicked, this.gui)

	if(this.gameData.karma > 10)
	    this.gameData.karma = 10
	if(this.gameData.karma > 0)
	    this.gameData.karma /= 1.5

	this.gameData.tiles_droped++

	var spawnTime = this.spawn_time(this.gameData.tiles_cleared)
	this.game.time.events.add(spawnTime,
				  this.spawn_box,
				  this);
    },

    spawn_time: function(tiles){
	var min_speed = 0.8
	var start_speed = 4.0
	this.speed = min_speed +
	    ((start_speed - min_speed) *
	     Math.pow(0.9, Math.trunc(tiles/10)))
	return this.speed * Phaser.Timer.SECOND
    },
    update: function(){
	this.stars.tilePosition.y += 2.5 / this.speed;
    }
};
<|endoftext|>


<commit_before>var path = require('path');
var url = require('url');
var express = require('express');
var minimist = require('minimist');
var ws = require('ws');
var kurento = require('kurento-client');
var fs    = require('fs');
var https = require('https');
var http = require('http');
var CONFIG = require('./config.js')
var path = require('path')

var favicon = require('serve-favicon');

var argv = minimist(process.argv.slice(2), {
    default: {
        as_uri: 'https://localhost:1338',
        ws_uri: 'ws://192.241.244.126:8888/kurento'
    }
});

var options =
{
  key:  fs.readFileSync('keys/server.key'),
  cert: fs.readFileSync('keys/server.crt')
};
//
var app = express();

/*
 * Definition of global variables.
 */
var idCounter = 0;
var candidatesQueue = {};
var kurentoClient = null;
var presenter = null;
var viewers = [];
var noPresenterMessage = 'No active presenter. Try again later...';

/*
 * Server startup
 */
var asUrl;
var port;
var server;

if (true) {  //set to process.env.ON_HEROKU for production set to false to test locally
  // run with http server
  port = process.env.PORT || 8080;
  server = http.createServer(app).listen(port, function() {
    console.log('Running on port ' + port + ' on Heroku');
  });
} else {
  asUrl = url.parse(argv.as_uri);
  port = asUrl.port;
  server = https.createServer(options, app).listen(port, function() {
    console.log('Open ' + url.format(asUrl) + ' with a WebRTC capable browser');
  });
}

// uses the web server created above
var wss = new ws.Server({
    server : server,
    path : '/one2many'
});

function nextUniqueId() {
  idCounter++;
  return idCounter.toString();
}

/*
 * Management of WebSocket messages
 */
wss.on('connection', function(ws) {

  var sessionId = nextUniqueId();
  console.log('Connection received with sessionId ' + sessionId);

    ws.on('error', function(error) {
        console.log('Connection ' + sessionId + ' error');
        stop(sessionId);
    });

    ws.on('close', function() {
        console.log('Connection ' + sessionId + ' closed');
        stop(sessionId);
    });

    ws.on('message', function(_message) {
        var message = JSON.parse(_message);
        console.log('Connection ' + sessionId + ' received message ', message);

        switch (message.id) {
        case 'presenter':
      startPresenter(sessionId, ws, message.sdpOffer, function(error, sdpAnswer) {
        if (error) {
          return ws.send(JSON.stringify({
            id : 'presenterResponse',
            response : 'rejected',
            message : error
          }));
        }
        ws.send(JSON.stringify({
          id : 'presenterResponse',
          response : 'accepted',
          sdpAnswer : sdpAnswer
        }));
      });
      break;

        case 'viewer':
      startViewer(sessionId, ws, message.sdpOffer, function(error, sdpAnswer) {
        if (error) {
          return ws.send(JSON.stringify({
            id : 'viewerResponse',
            response : 'rejected',
            message : error
          }));
        }

        ws.send(JSON.stringify({
          id : 'viewerResponse',
          response : 'accepted',
          sdpAnswer : sdpAnswer
        }));
      });
      break;

        case 'stop':
            stop(sessionId);
            break;

        case 'onIceCandidate':
            onIceCandidate(sessionId, message.candidate);
            break;

        default:
            ws.send(JSON.stringify({
                id : 'error',
                message : 'Invalid message ' + message
            }));
            break;
        }
    });
});

/*
 * Definition of functions
 */

// Recover kurentoClient for the first time.
function getKurentoClient(callback) {
    if (kurentoClient !== null) {
        return callback(null, kurentoClient);
    }

    kurento(argv.ws_uri, function(error, _kurentoClient) {
        if (error) {
            console.log("Could not find media server at address " + argv.ws_uri);
            return callback("Could not find media server at address" + argv.ws_uri
                    + ". Exiting with error " + error);
        }

        kurentoClient = _kurentoClient;
        callback(null, kurentoClient);
    });
}

function startPresenter(sessionId, ws, sdpOffer, callback) {
  clearCandidatesQueue(sessionId);

  if (presenter !== null) {
    stop(sessionId);
    return callback("Another user is currently acting as presenter. Try again later ...");
  }

  presenter = {
    id : sessionId,
    pipeline : null,
    webRtcEndpoint : null
  }

  getKurentoClient(function(error, kurentoClient) {
    if (error) {
      stop(sessionId);
      return callback(error);
    }

    if (presenter === null) {
      stop(sessionId);
      return callback(noPresenterMessage);
    }

    kurentoClient.create('MediaPipeline', function(error, pipeline) {
      if (error) {
        stop(sessionId);
        return callback(error);
      }

      if (presenter === null) {
        stop(sessionId);
        return callback(noPresenterMessage);
      }

      presenter.pipeline = pipeline;
      pipeline.create('WebRtcEndpoint', function(error, webRtcEndpoint) {
        if (error) {
          stop(sessionId);
          return callback(error);
        }

        if (presenter === null) {
          stop(sessionId);
          return callback(noPresenterMessage);
        }

        presenter.webRtcEndpoint = webRtcEndpoint;

                if (candidatesQueue[sessionId]) {
                    while(candidatesQueue[sessionId].length) {
                        var candidate = candidatesQueue[sessionId].shift();
                        webRtcEndpoint.addIceCandidate(candidate);
                    }
                }

                webRtcEndpoint.on('OnIceCandidate', function(event) {
                    var candidate = kurento.register.complexTypes.IceCandidate(event.candidate);
                    ws.send(JSON.stringify({
                        id : 'iceCandidate',
                        candidate : candidate
                    }));
                });

        webRtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer) {
          if (error) {
            stop(sessionId);
            return callback(error);
          }

          if (presenter === null) {
            stop(sessionId);
            return callback(noPresenterMessage);
          }

          callback(null, sdpAnswer);
        });

                webRtcEndpoint.gatherCandidates(function(error) {
                    if (error) {
                        stop(sessionId);
                        return callback(error);
                    }
                });
            });
        });
  });
}

function startViewer(sessionId, ws, sdpOffer, callback) {
  clearCandidatesQueue(sessionId);

  if (presenter === null) {
    stop(sessionId);
    return callback(noPresenterMessage);
  }

  presenter.pipeline.create('WebRtcEndpoint', function(error, webRtcEndpoint) {
    if (error) {
      stop(sessionId);
      return callback(error);
    }
    viewers[sessionId] = {
      "webRtcEndpoint" : webRtcEndpoint,
      "ws" : ws
    }

    if (presenter === null) {
      stop(sessionId);
      return callback(noPresenterMessage);
    }

    if (candidatesQueue[sessionId]) {
      while(candidatesQueue[sessionId].length) {
        var candidate = candidatesQueue[sessionId].shift();
        webRtcEndpoint.addIceCandidate(candidate);
      }
    }

        webRtcEndpoint.on('OnIceCandidate', function(event) {
            var candidate = kurento.register.complexTypes.IceCandidate(event.candidate);
            ws.send(JSON.stringify({
                id : 'iceCandidate',
                candidate : candidate
            }));
        });

    webRtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer) {
      if (error) {
        stop(sessionId);
        return callback(error);
      }
      if (presenter === null) {
        stop(sessionId);
        return callback(noPresenterMessage);
      }

      presenter.webRtcEndpoint.connect(webRtcEndpoint, function(error) {
        if (error) {
          stop(sessionId);
          return callback(error);
        }
        if (presenter === null) {
          stop(sessionId);
          return callback(noPresenterMessage);
        }

        callback(null, sdpAnswer);
            webRtcEndpoint.gatherCandidates(function(error) {
                if (error) {
                  stop(sessionId);
                  return callback(error);
                }
            });
        });
      });
  });
}

function clearCandidatesQueue(sessionId) {
  if (candidatesQueue[sessionId]) {
    delete candidatesQueue[sessionId];
  }
}

function stop(sessionId) {
  if (presenter !== null && presenter.id == sessionId) {
    for (var i in viewers) {
      var viewer = viewers[i];
      if (viewer.ws) {
        viewer.ws.send(JSON.stringify({
          id : 'stopCommunication'
        }));
      }
    }
    presenter.pipeline.release();
    presenter = null;
    viewers = [];

  } else if (viewers[sessionId]) {
    viewers[sessionId].webRtcEndpoint.release();
    delete viewers[sessionId];
  }

  clearCandidatesQueue(sessionId);
}

function onIceCandidate(sessionId, _candidate) {
    var candidate = kurento.register.complexTypes.IceCandidate(_candidate);

    if (presenter && presenter.id === sessionId && presenter.webRtcEndpoint) {
        console.info('Sending presenter candidate');
        presenter.webRtcEndpoint.addIceCandidate(candidate);
    }
    else if (viewers[sessionId] && viewers[sessionId].webRtcEndpoint) {
        console.info('Sending viewer candidate');
        viewers[sessionId].webRtcEndpoint.addIceCandidate(candidate);
    }
    else {
        console.info('Queueing candidate');
        if (!candidatesQueue[sessionId]) {
            candidatesQueue[sessionId] = [];
        }
        candidatesQueue[sessionId].push(candidate);
    }
}

///////////////////////////////////////////////\

var jwt = require('jsonwebtoken');
var expressJWT = require('express-jwt')
var bodyParser = require('body-parser');
var passport = require('passport')
    , FacebookStrategy = require('passport-facebook').Strategy;

app.use(favicon(__dirname + '/client/public/img/spinner.gif'));

app.use(bodyParser.json());

app.use(express.static(path.join(__dirname, 'client')));
//app.get('*', function (request, response){
//    response.sendFile(path.resolve(__dirname, 'client', 'index.html'))
//})
app.use(expressJWT({secret : CONFIG.JWT_SECRET}).unless({path : ['/',/^\/auth\/.*/,'/authenticateFacebook']}));

app.post('/auth/getToken/', (req, res) => {
    if (req.body.userName == 'tds@tds.com' && req.body.password == 'tds') {
        var myToken = jwt.sign({userName:req.body.userName},CONFIG.JWT_SECRET)
        res.status(200)
            .json({token: myToken});
    } else {
        res.sendStatus(403);
    }
});

app.get('/getData/', (req, res) => {
    res.status(200)
        .json({data: 'Valid JWT found! This protected data was fetched from the server.'});

})
passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(obj, done) {
    done(null, obj);
});

passport.use(new FacebookStrategy({
        clientID: CONFIG.FB_CLIENT_ID,
        clientSecret: CONFIG.FB_APP_SECRET,
        callbackURL: CONFIG.FB_CALL_BACK
    },
    function(accessToken, refreshToken, profile, done) {
        //User.findOrCreate(..., function(err, user) {
        //    if (err) { return done(err); }
        //    done(null, user);
        //});
        return done(null,{username : 'tds@tds.com'})
    }
));

app.use(passport.initialize());

app.get('/auth/facebook/',
    passport.authenticate('facebook'));

var token;

app.get('/auth/facebook/callback/',

    passport.authenticate('facebook', { failureRedirect: '/login' }),

    function(req, res) {
        token = jwt.sign({userName:'tds@tds.com'},CONFIG.JWT_SECRET)
        res.redirect('/#/authenticateFacebook')
    }

);

app.get('/auth/validateSocialToken',(req, res) => {

    res.json({token: token});
})

module.exports.server = server;

<commit_msg>(MEGRE) HTTPS error<commit_after>var path = require('path');
var url = require('url');
var express = require('express');
var minimist = require('minimist');
var ws = require('ws');
var kurento = require('kurento-client');
var fs    = require('fs');
var https = require('https');
var http = require('http');
var CONFIG = require('./config.js')
var path = require('path')

var favicon = require('serve-favicon');

var argv = minimist(process.argv.slice(2), {
    default: {
        as_uri: 'https://localhost:1338',
        ws_uri: 'ws://192.241.244.126:8888/kurento'
    }
});

var options =
{
  key:  fs.readFileSync('keys/server.key'),
  cert: fs.readFileSync('keys/server.crt')
};
//
var app = express();

/*
 * Definition of global variables.
 */
var idCounter = 0;
var candidatesQueue = {};
var kurentoClient = null;
var presenter = null;
var viewers = [];
var noPresenterMessage = 'No active presenter. Try again later...';

/*
 * Server startup
 */
var asUrl;
var port;
var server;

if (false) {  //set to process.env.ON_HEROKU for production set to false to test locally
  // run with http server
  port = process.env.PORT;
  server = http.createServer(app).listen(port, function() {
    console.log('Running on port ' + port + ' on Heroku');
  });
} else {
  asUrl = url.parse(argv.as_uri);
  port = asUrl.port;
  server = https.createServer(options, app).listen(port, function() {
    console.log('Open ' + url.format(asUrl) + ' with a WebRTC capable browser');
  });
}

// uses the web server created above
var wss = new ws.Server({
    server : server,
    path : '/one2many'
});

function nextUniqueId() {
  idCounter++;
  return idCounter.toString();
}

/*
 * Management of WebSocket messages
 */
wss.on('connection', function(ws) {

  var sessionId = nextUniqueId();
  console.log('Connection received with sessionId ' + sessionId);

    ws.on('error', function(error) {
        console.log('Connection ' + sessionId + ' error');
        stop(sessionId);
    });

    ws.on('close', function() {
        console.log('Connection ' + sessionId + ' closed');
        stop(sessionId);
    });

    ws.on('message', function(_message) {
        var message = JSON.parse(_message);
        console.log('Connection ' + sessionId + ' received message ', message);

        switch (message.id) {
        case 'presenter':
      startPresenter(sessionId, ws, message.sdpOffer, function(error, sdpAnswer) {
        if (error) {
          return ws.send(JSON.stringify({
            id : 'presenterResponse',
            response : 'rejected',
            message : error
          }));
        }
        ws.send(JSON.stringify({
          id : 'presenterResponse',
          response : 'accepted',
          sdpAnswer : sdpAnswer
        }));
      });
      break;

        case 'viewer':
      startViewer(sessionId, ws, message.sdpOffer, function(error, sdpAnswer) {
        if (error) {
          return ws.send(JSON.stringify({
            id : 'viewerResponse',
            response : 'rejected',
            message : error
          }));
        }

        ws.send(JSON.stringify({
          id : 'viewerResponse',
          response : 'accepted',
          sdpAnswer : sdpAnswer
        }));
      });
      break;

        case 'stop':
            stop(sessionId);
            break;

        case 'onIceCandidate':
            onIceCandidate(sessionId, message.candidate);
            break;

        default:
            ws.send(JSON.stringify({
                id : 'error',
                message : 'Invalid message ' + message
            }));
            break;
        }
    });
});

/*
 * Definition of functions
 */

// Recover kurentoClient for the first time.
function getKurentoClient(callback) {
    if (kurentoClient !== null) {
        return callback(null, kurentoClient);
    }

    kurento(argv.ws_uri, function(error, _kurentoClient) {
        if (error) {
            console.log("Could not find media server at address " + argv.ws_uri);
            return callback("Could not find media server at address" + argv.ws_uri
                    + ". Exiting with error " + error);
        }

        kurentoClient = _kurentoClient;
        callback(null, kurentoClient);
    });
}

function startPresenter(sessionId, ws, sdpOffer, callback) {
  clearCandidatesQueue(sessionId);

  if (presenter !== null) {
    stop(sessionId);
    return callback("Another user is currently acting as presenter. Try again later ...");
  }

  presenter = {
    id : sessionId,
    pipeline : null,
    webRtcEndpoint : null
  }

  getKurentoClient(function(error, kurentoClient) {
    if (error) {
      stop(sessionId);
      return callback(error);
    }

    if (presenter === null) {
      stop(sessionId);
      return callback(noPresenterMessage);
    }

    kurentoClient.create('MediaPipeline', function(error, pipeline) {
      if (error) {
        stop(sessionId);
        return callback(error);
      }

      if (presenter === null) {
        stop(sessionId);
        return callback(noPresenterMessage);
      }

      presenter.pipeline = pipeline;
      pipeline.create('WebRtcEndpoint', function(error, webRtcEndpoint) {
        if (error) {
          stop(sessionId);
          return callback(error);
        }

        if (presenter === null) {
          stop(sessionId);
          return callback(noPresenterMessage);
        }

        presenter.webRtcEndpoint = webRtcEndpoint;

                if (candidatesQueue[sessionId]) {
                    while(candidatesQueue[sessionId].length) {
                        var candidate = candidatesQueue[sessionId].shift();
                        webRtcEndpoint.addIceCandidate(candidate);
                    }
                }

                webRtcEndpoint.on('OnIceCandidate', function(event) {
                    var candidate = kurento.register.complexTypes.IceCandidate(event.candidate);
                    ws.send(JSON.stringify({
                        id : 'iceCandidate',
                        candidate : candidate
                    }));
                });

        webRtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer) {
          if (error) {
            stop(sessionId);
            return callback(error);
          }

          if (presenter === null) {
            stop(sessionId);
            return callback(noPresenterMessage);
          }

          callback(null, sdpAnswer);
        });

                webRtcEndpoint.gatherCandidates(function(error) {
                    if (error) {
                        stop(sessionId);
                        return callback(error);
                    }
                });
            });
        });
  });
}

function startViewer(sessionId, ws, sdpOffer, callback) {
  clearCandidatesQueue(sessionId);

  if (presenter === null) {
    stop(sessionId);
    return callback(noPresenterMessage);
  }

  presenter.pipeline.create('WebRtcEndpoint', function(error, webRtcEndpoint) {
    if (error) {
      stop(sessionId);
      return callback(error);
    }
    viewers[sessionId] = {
      "webRtcEndpoint" : webRtcEndpoint,
      "ws" : ws
    }

    if (presenter === null) {
      stop(sessionId);
      return callback(noPresenterMessage);
    }

    if (candidatesQueue[sessionId]) {
      while(candidatesQueue[sessionId].length) {
        var candidate = candidatesQueue[sessionId].shift();
        webRtcEndpoint.addIceCandidate(candidate);
      }
    }

        webRtcEndpoint.on('OnIceCandidate', function(event) {
            var candidate = kurento.register.complexTypes.IceCandidate(event.candidate);
            ws.send(JSON.stringify({
                id : 'iceCandidate',
                candidate : candidate
            }));
        });

    webRtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer) {
      if (error) {
        stop(sessionId);
        return callback(error);
      }
      if (presenter === null) {
        stop(sessionId);
        return callback(noPresenterMessage);
      }

      presenter.webRtcEndpoint.connect(webRtcEndpoint, function(error) {
        if (error) {
          stop(sessionId);
          return callback(error);
        }
        if (presenter === null) {
          stop(sessionId);
          return callback(noPresenterMessage);
        }

        callback(null, sdpAnswer);
            webRtcEndpoint.gatherCandidates(function(error) {
                if (error) {
                  stop(sessionId);
                  return callback(error);
                }
            });
        });
      });
  });
}

function clearCandidatesQueue(sessionId) {
  if (candidatesQueue[sessionId]) {
    delete candidatesQueue[sessionId];
  }
}

function stop(sessionId) {
  if (presenter !== null && presenter.id == sessionId) {
    for (var i in viewers) {
      var viewer = viewers[i];
      if (viewer.ws) {
        viewer.ws.send(JSON.stringify({
          id : 'stopCommunication'
        }));
      }
    }
    presenter.pipeline.release();
    presenter = null;
    viewers = [];

  } else if (viewers[sessionId]) {
    viewers[sessionId].webRtcEndpoint.release();
    delete viewers[sessionId];
  }

  clearCandidatesQueue(sessionId);
}

function onIceCandidate(sessionId, _candidate) {
    var candidate = kurento.register.complexTypes.IceCandidate(_candidate);

    if (presenter && presenter.id === sessionId && presenter.webRtcEndpoint) {
        console.info('Sending presenter candidate');
        presenter.webRtcEndpoint.addIceCandidate(candidate);
    }
    else if (viewers[sessionId] && viewers[sessionId].webRtcEndpoint) {
        console.info('Sending viewer candidate');
        viewers[sessionId].webRtcEndpoint.addIceCandidate(candidate);
    }
    else {
        console.info('Queueing candidate');
        if (!candidatesQueue[sessionId]) {
            candidatesQueue[sessionId] = [];
        }
        candidatesQueue[sessionId].push(candidate);
    }
}

///////////////////////////////////////////////\

var jwt = require('jsonwebtoken');
var expressJWT = require('express-jwt')
var bodyParser = require('body-parser');
var passport = require('passport')
    , FacebookStrategy = require('passport-facebook').Strategy;

app.use(favicon(__dirname + '/client/public/img/spinner.gif'));

app.use(bodyParser.json());

app.use(express.static(path.join(__dirname, 'client')));
//app.get('*', function (request, response){
//    response.sendFile(path.resolve(__dirname, 'client', 'index.html'))
//})
app.use(expressJWT({secret : CONFIG.JWT_SECRET}).unless({path : ['/',/^\/auth\/.*/,'/authenticateFacebook']}));

app.post('/auth/getToken/', (req, res) => {
    if (req.body.userName == 'tds@tds.com' && req.body.password == 'tds') {
        var myToken = jwt.sign({userName:req.body.userName},CONFIG.JWT_SECRET)
        res.status(200)
            .json({token: myToken});
    } else {
        res.sendStatus(403);
    }
});

app.get('/getData/', (req, res) => {
    res.status(200)
        .json({data: 'Valid JWT found! This protected data was fetched from the server.'});

})
passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(obj, done) {
    done(null, obj);
});

passport.use(new FacebookStrategy({
        clientID: CONFIG.FB_CLIENT_ID,
        clientSecret: CONFIG.FB_APP_SECRET,
        callbackURL: CONFIG.FB_CALL_BACK
    },
    function(accessToken, refreshToken, profile, done) {
        //User.findOrCreate(..., function(err, user) {
        //    if (err) { return done(err); }
        //    done(null, user);
        //});
        return done(null,{username : 'tds@tds.com'})
    }
));

app.use(passport.initialize());

app.get('/auth/facebook/',
    passport.authenticate('facebook'));

var token;

app.get('/auth/facebook/callback/',

    passport.authenticate('facebook', { failureRedirect: '/login' }),

    function(req, res) {
        token = jwt.sign({userName:'tds@tds.com'},CONFIG.JWT_SECRET)
        res.redirect('/#/authenticateFacebook')
    }

);

app.get('/auth/validateSocialToken',(req, res) => {

    res.json({token: token});
})

module.exports.server = server;

<|endoftext|>


<commit_before>const {GameLost} = require('./exceptions');
const Direction = require('./direction');

class Game {
  static GAME_READY = 'ready';
  static GAME_RUNNING = 'running';
  static GAME_WON = 'won';
  static GAME_LOST = 'lost';

  constructor(grid) {
    this.grid = grid;
    this.state = Game.GAME_READY;
    this.stateMessage = '';
  }

  get snakeSize() {
    return this.grid.snake.size;
  }

  handleKey(key) {
    if (!Game.isRunning(this.state)) {
      return;
    }

    let direction = null;
    if (key === 38) { // UP
      direction = Direction.N;
    }
    else if (key === 39) { // RIGHT
      direction = Direction.E;
    }
    else if (key === 37) { // LEFT
      direction = Direction.W;
    }
    else if (key === 40) { // DOWN
      direction = Direction.S;
    }

    if (direction && this.grid.snake.canTravelInDirection(direction)) {
      this.grid.snake.setDirection(direction);
    }
  }

  update() {
    if (!Game.isRunning(this.state)) {
      return;
    }

    try {
      this.grid.update();
    }
    catch (error) {
      if (error instanceof GameLost) {
        this.finishGame(error);
        return;
      }
      else {
        throw error;
      }
    }

    if (this.grid.isFull) {
      this.finishGame();
    }
  }

  /**
   * Finishes the game. If an error is provided,
   * the game is lost and the error's message is
   * used as the failure message
   * If nothing is provided, the game is won
   */
  finishGame(error = null) {
    if (!error) {
      this.state = Game.GAME_WON;
      this.stateMessage = 'you did it';
    }
    else {
      this.state = Game.GAME_LOST;
      this.stateMessage = error.message;
    }
  }

  render() {
    return {
      state: this.state,
      message: this.stateMessage,
      grid: this.grid.render(),
    };
  }

  static isReady(state) {
    return state === this.GAME_READY;
  }

  static isRunning(state) {
    return state === this.GAME_RUNNING;
  }

  static isWon(state) {
    return state === this.GAME_WON;
  }

  static isLost(state) {
    return state === this.GAME_LOST;
  }
}

module.exports = Game;

<commit_msg>Made it so the game starts when you hit the arrow keys<commit_after>const {GameLost} = require('./exceptions');
const Direction = require('./direction');

const KEYS = {
  UP_ARROW: 38,
  RIGHT_ARROW: 39,
  LEFT_ARROW: 37,
  DOWN_ARROW: 40,
};
const ARROW_KEYS = new Set(
  Object.keys(KEYS)
    .filter((k) => k.includes('ARROW'))
    .map((k) => KEYS[k])
);

class Game {
  static GAME_READY = 'ready';
  static GAME_RUNNING = 'running';
  static GAME_WON = 'won';
  static GAME_LOST = 'lost';

  constructor(grid) {
    this.grid = grid;
    this.state = Game.GAME_READY;
    this.stateMessage = '';
  }

  get snakeSize() {
    return this.grid.snake.size;
  }

  handleKey(key) {
    const isRunning = Game.isRunning(this.state);
    if (!isRunning) {
      if (ARROW_KEYS.has(key)) {
        this.state = Game.GAME_RUNNING;
      }
      else {
        return;
      }
    }

    let direction = null;
    if (key === KEYS.UP_ARROW) {
      direction = Direction.N;
    }
    else if (key === KEYS.RIGHT_ARROW) {
      direction = Direction.E;
    }
    else if (key === KEYS.LEFT_ARROW) {
      direction = Direction.W;
    }
    else if (key === KEYS.DOWN_ARROW) {
      direction = Direction.S;
    }

    if (direction && this.grid.snake.canTravelInDirection(direction)) {
      this.grid.snake.setDirection(direction);
    }
  }

  update() {
    if (!Game.isRunning(this.state)) {
      return;
    }

    try {
      this.grid.update();
    }
    catch (error) {
      if (error instanceof GameLost) {
        this.finishGame(error);
        return;
      }
      else {
        throw error;
      }
    }

    if (this.grid.isFull) {
      this.finishGame();
    }
  }

  /**
   * Finishes the game. If an error is provided,
   * the game is lost and the error's message is
   * used as the failure message
   * If nothing is provided, the game is won
   */
  finishGame(error = null) {
    if (!error) {
      this.state = Game.GAME_WON;
      this.stateMessage = 'you did it';
    }
    else {
      this.state = Game.GAME_LOST;
      this.stateMessage = error.message;
    }
  }

  render() {
    return {
      state: this.state,
      message: this.stateMessage,
      grid: this.grid.render(),
    };
  }

  static isReady(state) {
    return state === this.GAME_READY;
  }

  static isRunning(state) {
    return state === this.GAME_RUNNING;
  }

  static isWon(state) {
    return state === this.GAME_WON;
  }

  static isLost(state) {
    return state === this.GAME_LOST;
  }
}

module.exports = Game;

<|endoftext|>


<commit_before>/*jslint node: true, indent: 4 */
/* eslint-disable no-console */
'use strict';
var database = require('./data'),
    checks = require('./check'),
    http = require('http'),
    url = require('url'),
    path = require('path'),
    fs = require('fs'),
    mustache = require('mustache'),
    yaml = require('js-yaml');
var port = parseInt(process.env.PORT || 8888, 10),
    ip = process.env.IP || undefined;

checks.start();

function serveStatic(filename, response) {
    fs.exists(filename, function (exists) {
        if (!exists) {
            return render404Error(response);
        }

        if (fs.statSync(filename).isDirectory()) {
            filename += '/index.html';
        }

        fs.readFile(filename, 'binary', function (err, file) {
            if (err) {
                return render500Error(err, response);
            }

            response.writeHead(200);
            response.write(file, 'binary');
            response.end();
        });
    });
}

function formatJSON(data, callback) {
    try {
        data = JSON.stringify(data, undefined, '\t');
    } catch (e) {
        return callback(e);
    }
    callback(null, data);
}

function formatYAML(data, callback) {
    try {
        data = yaml.safeDump(data,{skipInvalid:true});
    } catch (e) {
        return callback(e);
    }
    callback(null, data);
}

function formatHTML(data, template, callback) {
    if (typeof (template) === 'function') {
        callback = template;
        template = 'index.html';
    }
    fs.readFile(path.join(process.cwd(), 'templates', template),
        'binary',
        function (err, file) {
            if (err) {
                return callback(err);
            }
            try {
                callback(null, mustache.render(file, data));
            } catch (e) {
                callback(e);
            }
        });
}

http.createServer(function (request, response) {
    var uri = url.parse(request.url).pathname,
        filename = path.join(process.cwd(), uri);

    console.log(uri);
    if (/^\/static/.test(uri)) {
        serveStatic(filename, response);
    } else if (/^\/(index[.](html?|json|yml))?$/i.test(uri)) {
        var formatter = formatHTML,
            accept = request.headers.accept;
        uri = uri.toLowerCase();
        if (uri === '/index.json' || accept === 'application/json') {
            formatter = formatJSON;
        } else if (uri === '/index.yml' || accept === 'application/yaml') {
            formatter = formatYAML;
        }
        database.getData({
            dataPeriod: 5 * 60,
            host: request.headers.host
        }, function (err, data) {
            if (err) {
                return render500Error(err, response);
            }
            formatter(data, function (err2, data2) {
                if (err2) {
                    return render500Error(err2, response);
                }
                response.writeHead(200);
                response.write(data2, 'binary');
                response.end();
            });
        });
    } else {
        render404Error(response);
    }
}).listen(port, ip);

function render404Error(response) {
    formatHTML(null, 'error404.html', function (err, data) {
        if (err) {
            response.writeHead(404, {
                'Content-Type': 'text/plain'
            });
            response.write('404 Not Found\n');
            return response.end();
        }
        response.writeHead(404);
        response.write(data, 'binary');
        response.end();
    });
}

function render500Error(err, response) {
    formatHTML(null, 'error500.html', function (err2, data) {
        if (err || err2) {
            response.writeHead(500, {
                'Content-Type': 'text/plain'
            });
            response.write(err + '\n');
            return response.end();
        }
        response.writeHead(500);
        response.write(data, 'binary');
        response.end();
    });
}
<commit_msg>make dataPeriod configurable<commit_after>/*jslint node: true, indent: 4 */
/* eslint-disable no-console */
'use strict';
var database = require('./data'),
    checks = require('./check'),
    config = require('./config.json'),
    http = require('http'),
    url = require('url'),
    path = require('path'),
    fs = require('fs'),
    mustache = require('mustache'),
    yaml = require('js-yaml');
var port = parseInt(process.env.PORT || 8888, 10),
    ip = process.env.IP || undefined;

checks.start();

function serveStatic(filename, response) {
    fs.exists(filename, function (exists) {
        if (!exists) {
            return render404Error(response);
        }

        if (fs.statSync(filename).isDirectory()) {
            filename += '/index.html';
        }

        fs.readFile(filename, 'binary', function (err, file) {
            if (err) {
                return render500Error(err, response);
            }

            response.writeHead(200);
            response.write(file, 'binary');
            response.end();
        });
    });
}

function formatJSON(data, callback) {
    try {
        data = JSON.stringify(data, undefined, '\t');
    } catch (e) {
        return callback(e);
    }
    callback(null, data);
}

function formatYAML(data, callback) {
    try {
        data = yaml.safeDump(data,{skipInvalid:true});
    } catch (e) {
        return callback(e);
    }
    callback(null, data);
}

function formatHTML(data, template, callback) {
    if (typeof (template) === 'function') {
        callback = template;
        template = 'index.html';
    }
    fs.readFile(path.join(process.cwd(), 'templates', template),
        'binary',
        function (err, file) {
            if (err) {
                return callback(err);
            }
            try {
                callback(null, mustache.render(file, data));
            } catch (e) {
                callback(e);
            }
        });
}

http.createServer(function (request, response) {
    var uri = url.parse(request.url).pathname,
        filename = path.join(process.cwd(), uri);

    console.log(uri);
    if (/^\/static/.test(uri)) {
        serveStatic(filename, response);
    } else if (/^\/(index[.](html?|json|yml))?$/i.test(uri)) {
        var formatter = formatHTML,
            accept = request.headers.accept;
        uri = uri.toLowerCase();
        if (uri === '/index.json' || accept === 'application/json') {
            formatter = formatJSON;
        } else if (uri === '/index.yml' || accept === 'application/yaml') {
            formatter = formatYAML;
        }
        database.getData({
            dataPeriod: config.dataPeriod,
            host: request.headers.host
        }, function (err, data) {
            if (err) {
                return render500Error(err, response);
            }
            formatter(data, function (err2, data2) {
                if (err2) {
                    return render500Error(err2, response);
                }
                response.writeHead(200);
                response.write(data2, 'binary');
                response.end();
            });
        });
    } else {
        render404Error(response);
    }
}).listen(port, ip);

function render404Error(response) {
    formatHTML(null, 'error404.html', function (err, data) {
        if (err) {
            response.writeHead(404, {
                'Content-Type': 'text/plain'
            });
            response.write('404 Not Found\n');
            return response.end();
        }
        response.writeHead(404);
        response.write(data, 'binary');
        response.end();
    });
}

function render500Error(err, response) {
    formatHTML(null, 'error500.html', function (err2, data) {
        if (err || err2) {
            response.writeHead(500, {
                'Content-Type': 'text/plain'
            });
            response.write(err + '\n');
            return response.end();
        }
        response.writeHead(500);
        response.write(data, 'binary');
        response.end();
    });
}
<|endoftext|>


<commit_before>var express    = require('express');        // call express
var app        = express();                 // define our app using express
var bodyParser = require('body-parser');
var https      = require('https');
var fs         = require('fs');
var model      = require('./lib/model.js');

var options = {
    key: fs.readFileSync('./ca.key'),
    cert: fs.readFileSync('./ca.crt'),
};

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use("/js", express.static(__dirname + '/public/js')); // javascript folder
app.use("/css", express.static(__dirname + '/public/css')); // css folder

var port = process.env.PORT || 8443;        // set our port

var router = express.Router();              // get an instance of the express Router

router.get('/', function(req, res) {
   res.sendFile(__dirname + '/views/index.html');
});

router.post('/file', function(req, res) {
    // need the filename
    // need the content
    if (req.body.filename == undefined || req.body.content == undefined) {
        res.end("{}");
    } else {
        model.createFile(req.body.filename, function (file) {
            console.log(file);
            res.send(file._id);
        });
    }
});

router.get('/file/:id', function (req, res) {
    id = req.params.id.split('#')[0];
    model.getFile(id, function (file) {
        console.log(file);
        if (file.length > 0) {
            res.send(file[0]._id);
        } else {
            res.send("File Not Found");
        }
    });
});

app.use('/', router);

var server = https.createServer(options, app).listen(port, function(){
  console.log("Magic happens on port " + port);
});<commit_msg>Added JSON response<commit_after>var express    = require('express');        // call express
var app        = express();                 // define our app using express
var bodyParser = require('body-parser');
var https      = require('https');
var fs         = require('fs');
var model      = require('./lib/model.js');

var options = {
    key: fs.readFileSync('./ca.key'),
    cert: fs.readFileSync('./ca.crt'),
};

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use("/js", express.static(__dirname + '/public/js')); // javascript folder
app.use("/css", express.static(__dirname + '/public/css')); // css folder

var port = process.env.PORT || 8443;        // set our port

var router = express.Router();              // get an instance of the express Router

router.get('/', function(req, res) {
   res.sendFile(__dirname + '/views/index.html');
});

router.post('/file', function(req, res) {
    // need the filename
    // need the content
    if (req.body.filename == undefined || req.body.content == undefined) {
        res.end("{}");
    } else {
        model.createFile(req.body.filename, function (file) {
            console.log(file);
            res.send("{'id': '" + file._id + "'}");
        });
    }
});

router.get('/file/:id', function (req, res) {
    id = req.params.id.split('#')[0];
    model.getFile(id, function (file) {
        console.log(file);
        if (file.length > 0) {
            res.send(file[0]._id);
        } else {
            res.send("File Not Found");
        }
    });
});

app.use('/', router);

var server = https.createServer(options, app).listen(port, function(){
  console.log("Magic happens on port " + port);
});<|endoftext|>