Пример #1
0
            public override void Process(ResourceManager resourceManager)
            {
                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                World startWorld = ResolveLocation(Context, "start", resourceManager, map);

                if (startWorld == null)
                {
                    return;
                }

                World endWorld = ResolveLocation(Context, "end", resourceManager, map);

                if (endWorld == null)
                {
                    return;
                }

                int jump = GetIntOption("jump", 2).Clamp(0, 12);

                var finder = new TravellerPathFinder(resourceManager, map, jump)
                {
                    RequireWildernessRefuelling = GetBoolOption("wild", false),
                    ImperialWorldsOnly          = GetBoolOption("im", false),
                    AvoidRedZones = GetBoolOption("nored", false)
                };
                List <World> route = finder.FindPath(startWorld, endWorld) ??
                                     throw new HttpError(404, "Not Found", "No route found");

                SendResult(route.Select(w => new Results.RouteStop(w)).ToList());
            }
Пример #2
0
            public override void Process(ResourceManager resourceManager)
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                Location loc;

                // Accept either sector [& hex] or sx,sy [& hx,hy] or x,y
                if (HasOption("sector"))
                {
                    string sectorName = GetStringOption("sector");
                    Sector sector     = map.FromName(sectorName) ??
                                        throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");

                    if (HasOption("subsector"))
                    {
                        string subsector = GetStringOption("subsector");
                        int    index     = sector.SubsectorIndexFor(subsector);
                        if (index == -1)
                        {
                            throw new HttpError(404, "Not Found", $"The specified subsector '{subsector}' was not found.");
                        }
                        loc = new Location(sector.Location, new Hex(
                                               (byte)(index % 4 * Astrometrics.SubsectorWidth + Astrometrics.SubsectorWidth / 2),
                                               (byte)(index / 4 * Astrometrics.SubsectorHeight + Astrometrics.SubsectorHeight / 2)));
                    }
                    else
                    {
                        int hex = GetIntOption("hex", 0);
                        loc = new Location(sector.Location, hex);
                    }
                }
                else if (HasLocation())
                {
                    loc = GetLocation();
                }
                else
                {
                    throw new HttpError(400, "Bad Request", "Must specify either sector name (and optional hex) or sx, sy (and optional hx, hy), or x, y (world-space coordinates).");
                }

                Point coords = Astrometrics.LocationToCoordinates(loc);

                SendResult(new Results.CoordinatesResult()
                {
                    SectorX = loc.Sector.X,
                    SectorY = loc.Sector.Y,
                    HexX    = loc.Hex.X,
                    HexY    = loc.Hex.Y,
                    X       = coords.X,
                    Y       = coords.Y
                });
            }
Пример #3
0
            public override void Process()
            {
                ResourceManager resourceManager = new ResourceManager(context.Server);

                MapOptions options = MapOptions.SectorGrid | MapOptions.BordersMajor | MapOptions.NamesMajor | MapOptions.NamesMinor;

                Stylesheet.Style style = Stylesheet.Style.Poster;
                ParseOptions(ref options, ref style);

                double x     = GetDoubleOption("x", 0);
                double y     = GetDoubleOption("y", 0);
                double scale = Util.Clamp(GetDoubleOption("scale", 0), MinScale, MaxScale);

                int width  = GetIntOption("w", NormalTileWidth);
                int height = GetIntOption("h", NormalTileHeight);

                if (width < 0 || height < 1)
                {
                    throw new HttpError(400, "Bad Request",
                                        string.Format("Requested dimensions ({0}x{1}) invalid.", width, height));
                }
                if (width * height > MaxDimension * MaxDimension)
                {
                    throw new HttpError(400, "Bad Request",
                                        string.Format("Requested dimensions ({0}x{1}) too large.", width, height));
                }


                Size tileSize = new Size(width, height);

                RectangleF tileRect = new RectangleF();

                tileRect.X      = (float)(x * tileSize.Width / (scale * Astrometrics.ParsecScaleX));
                tileRect.Y      = (float)(y * tileSize.Height / (scale * Astrometrics.ParsecScaleY));
                tileRect.Width  = (float)(tileSize.Width / (scale * Astrometrics.ParsecScaleX));
                tileRect.Height = (float)(tileSize.Height / (scale * Astrometrics.ParsecScaleY));

                DateTime dt    = DateTime.Now;
                bool     silly = (Math.Abs((int)x % 2) == Math.Abs((int)y % 2)) && (dt.Month == 4 && dt.Day == 1);

                silly = GetBoolOption("silly", silly);

                Selector      selector = new RectSelector(SectorMap.ForMilieu(resourceManager, GetStringOption("milieu")), resourceManager, tileRect);
                Stylesheet    styles   = new Stylesheet(scale, options, style);
                RenderContext ctx      = new RenderContext(resourceManager, selector, tileRect, scale, options, styles, tileSize);

                ctx.Silly = silly;
                ctx.ClipOutsectorBorders = true;
                ProduceResponse(context, "Tile", ctx, tileSize);
            }
Пример #4
0
            public override void Process()
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                ResourceManager resourceManager = new ResourceManager(context.Server);

                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                Sector           sector;

                if (context.Request.HttpMethod == "POST")
                {
                    var type   = SectorMetadataFileParser.SniffType(context.Request.InputStream);
                    var parser = SectorMetadataFileParser.ForType(type);
                    using (var reader = new System.IO.StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
                    {
                        sector = parser.Parse(reader);
                    }
                }
                else if (HasOption("sx") && HasOption("sy"))
                {
                    int sx = GetIntOption("sx", 0);
                    int sy = GetIntOption("sy", 0);

                    sector = map.FromLocation(sx, sy);

                    if (sector == null)
                    {
                        throw new HttpError(404, "Not Found", string.Format("The sector at {0},{1} was not found.", sx, sy));
                    }
                }
                else if (HasOption("sector"))
                {
                    string sectorName = GetStringOption("sector");
                    sector = map.FromName(sectorName);

                    if (sector == null)
                    {
                        throw new HttpError(404, "Not Found", string.Format("The specified sector '{0}' was not found.", sectorName));
                    }
                }
                else
                {
                    throw new HttpError(400, "Bad Request", "No sector specified.");
                }

                SendResult(context, new Results.SectorMetadata(sector, sector.GetWorlds(resourceManager, cacheResults: true)));
            }
Пример #5
0
            public override void Process()
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                ResourceManager resourceManager = new ResourceManager(context.Server);

                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                Sector           sector;

                if (HasOption("sx") && HasOption("sy"))
                {
                    int sx = GetIntOption("sx", 0);
                    int sy = GetIntOption("sy", 0);

                    sector = map.FromLocation(sx, sy);

                    if (sector == null)
                    {
                        throw new HttpError(404, "Not Found", string.Format("The sector at {0},{1} was not found.", sx, sy));
                    }
                }
                else if (HasOption("sector"))
                {
                    string sectorName = GetStringOption("sector");
                    sector = map.FromName(sectorName);

                    if (sector == null)
                    {
                        throw new HttpError(404, "Not Found", string.Format("The specified sector '{0}' was not found.", sectorName));
                    }
                }
                else
                {
                    throw new HttpError(400, "Bad Request", "No sector specified.");
                }

                string data;

                using (var writer = new StringWriter())
                {
                    new MSECSerializer().Serialize(writer, sector);
                    data = writer.ToString();
                }

                SendResult(context, data);
            }
Пример #6
0
            public override void Process(ResourceManager resourceManager)
            {
                MapOptions options = MapOptions.SectorGrid | MapOptions.BordersMajor | MapOptions.NamesMajor | MapOptions.NamesMinor;
                Style      style   = Style.Poster;

                ParseOptions(ref options, ref style);

                double x     = GetDoubleOption("x", 0);
                double y     = GetDoubleOption("y", 0);
                double scale = GetDoubleOption("scale", 0).Clamp(MinScale, MaxScale);

                int width  = GetIntOption("w", NormalTileWidth);
                int height = GetIntOption("h", NormalTileHeight);

                if (width < 1 || height < 1)
                {
                    throw new HttpError(400, "Bad Request",
                                        $"Requested dimensions ({width}x{height}) invalid.");
                }
                if (width * height > MaxDimension * MaxDimension)
                {
                    throw new HttpError(400, "Bad Request",
                                        $"Requested dimensions ({width}x{height}) too large.");
                }


                Size tileSize = new Size(width, height);

                RectangleF tileRect = new RectangleF()
                {
                    X      = (float)(x * tileSize.Width / (scale * Astrometrics.ParsecScaleX)),
                    Y      = (float)(y * tileSize.Height / (scale * Astrometrics.ParsecScaleY)),
                    Width  = (float)(tileSize.Width / (scale * Astrometrics.ParsecScaleX)),
                    Height = (float)(tileSize.Height / (scale * Astrometrics.ParsecScaleY))
                };
                DateTime dt = DateTime.Now;

                Selector      selector = new RectSelector(SectorMap.ForMilieu(resourceManager, GetStringOption("milieu")), resourceManager, tileRect);
                Stylesheet    styles   = new Stylesheet(scale, options, style);
                RenderContext ctx      = new RenderContext(resourceManager, selector, tileRect, scale, options, styles, tileSize)
                {
                    ClipOutsectorBorders = true
                };

                ProduceResponse(Context, "Tile", ctx, tileSize, AbstractMatrix.Identity);
            }
Пример #7
0
                public override void Process()
                {
                    ResourceManager resourceManager = new ResourceManager(context.Server);

                    MapOptions options = MapOptions.SectorGrid | MapOptions.FilledBorders;

                    Stylesheet.Style style = Stylesheet.Style.Poster;
                    ParseOptions(ref options, ref style);

                    float x        = -0.5f;
                    float y        = -0.5f;
                    float scale    = 2;
                    Size  tileSize = new Size(1000, 1000);

                    RectangleF tileRect = new RectangleF();

                    tileRect.X      = x * tileSize.Width / (scale * Astrometrics.ParsecScaleX);
                    tileRect.Y      = y * tileSize.Height / (scale * Astrometrics.ParsecScaleY);
                    tileRect.Width  = tileSize.Width / (scale * Astrometrics.ParsecScaleX);
                    tileRect.Height = tileSize.Height / (scale * Astrometrics.ParsecScaleY);

                    Selector selector = new RectSelector(
                        SectorMap.ForMilieu(resourceManager, GetStringOption("milieu")),
                        resourceManager,
                        tileRect);
                    Stylesheet styles = new Stylesheet(scale, options, style);

                    styles.microRoutes.visible       = true;
                    styles.macroRoutes.visible       = false;
                    styles.macroBorders.visible      = false;
                    styles.microBorders.visible      = true;
                    styles.capitals.visible          = false;
                    styles.worlds.visible            = true;
                    styles.worldDetails              = WorldDetails.Dotmap;
                    styles.showAllSectorNames        = false;
                    styles.showSomeSectorNames       = false;
                    styles.macroNames.visible        = false;
                    styles.pseudoRandomStars.visible = false;
                    styles.fillMicroBorders          = true;

                    RenderContext ctx = new RenderContext(resourceManager, selector, tileRect, scale, options, styles, tileSize);

                    ctx.ClipOutsectorBorders = true;

                    ProduceResponse(context, "Overview", ctx, tileSize);
                }
Пример #8
0
            public override void Process()
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                ResourceManager resourceManager = new ResourceManager(context.Server);

                //
                // Jump
                //
                int jump = Util.Clamp(GetIntOption("jump", 6), 0, 12);

                //
                // Coordinates
                //
                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                Location         loc = new Location(map.FromName("Spinward Marches").Location, 1910);

                if (HasOption("sector") && HasOption("hex"))
                {
                    string sectorName = GetStringOption("sector");
                    int    hex        = GetIntOption("hex", 0);
                    Sector sector     = map.FromName(sectorName);
                    if (sector == null)
                    {
                        throw new HttpError(404, "Not Found", string.Format("The specified sector '{0}' was not found.", sectorName));
                    }

                    loc = new Location(sector.Location, hex);
                }
                else if (HasLocation())
                {
                    loc = GetLocation();
                }

                Selector selector = new HexSelector(map, resourceManager, loc, jump);

                var data = new Results.JumpWorldsResult();

                data.Worlds.AddRange(selector.Worlds);
                SendResult(context, data);
            }
Пример #9
0
            public override void Process(ResourceManager resourceManager)
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                //
                // Jump
                //
                int jump = GetIntOption("jump", 6).Clamp(0, 12);

                //
                // Coordinates
                //
                Location loc = Location.Empty;

                if (HasOption("sector") && HasOption("hex"))
                {
                    string sectorName = GetStringOption("sector");
                    int    hex        = GetIntOption("hex", 0);
                    Sector sector     = map.FromName(sectorName) ??
                                        throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");

                    loc = new Location(sector.Location, hex);
                }
                else if (HasLocation())
                {
                    loc = GetLocation();
                }

                Selector selector = new HexSelector(map, resourceManager, loc, jump);

                var data = new Results.JumpWorldsResult();

                data.Worlds.AddRange(selector.Worlds);
                SendResult(data);
            }
Пример #10
0
            public override void Process(ResourceManager resourceManager)
            {
                Selector   selector;
                RectangleF tileRect;
                MapOptions options = MapOptions.SectorGrid | MapOptions.SubsectorGrid | MapOptions.BordersMajor | MapOptions.BordersMinor | MapOptions.NamesMajor | MapOptions.NamesMinor | MapOptions.WorldsCapitals | MapOptions.WorldsHomeworlds;
                Style      style   = Style.Poster;

                ParseOptions(ref options, ref style);
                string title;
                bool   clipOutsectorBorders;

                if (HasOption("x1") && HasOption("x2") &&
                    HasOption("y1") && HasOption("y2"))
                {
                    // Arbitrary rectangle

                    int x1 = GetIntOption("x1", 0);
                    int x2 = GetIntOption("x2", 0);
                    int y1 = GetIntOption("y1", 0);
                    int y2 = GetIntOption("y2", 0);

                    tileRect = new RectangleF()
                    {
                        X = Math.Min(x1, x2),
                        Y = Math.Min(y1, y2)
                    };
                    tileRect.Width  = Math.Max(x1, x2) - tileRect.X;
                    tileRect.Height = Math.Max(y1, y2) - tileRect.Y;

                    // NOTE: This (re)initializes a static data structure used for
                    // resolving names into sector locations, so needs to be run
                    // before any other objects (e.g. Worlds) are loaded.
                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                    selector = new RectSelector(map, resourceManager, tileRect, slop: false);

                    // Include specified hexes
                    tileRect.Offset(-1, -1);
                    tileRect.Width  += 1;
                    tileRect.Height += 1;

                    title = $"Poster ({x1},{y1}) - ({x2},{y2})";
                    clipOutsectorBorders = true;
                }
                else if (HasOption("domain"))
                {
                    string domain = GetStringOption("domain") !;
                    double x, y, w = 2, h = 2;
                    switch (domain.ToLowerInvariant())
                    {
                    case "deneb": x = -4; y = -1; title = "Domain of Deneb"; break;

                    case "vland": x = -2; y = -1; title = "Domain of Vland"; break;

                    case "ilelish": x = -2; y = 1; title = "Domain of Ilelish"; break;

                    case "antares": x = 0; y = -2; title = "Domain of Antares"; break;

                    case "sylea": x = 0; y = 0; title = "Domain of Sylea"; break;

                    case "sol": x = 0; y = 2; title = "Domain of Sol"; break;

                    case "gateway": x = 2; y = 0; title = "Domain of Gateway"; break;

                    // And these aren't domains, but...
                    case "foreven": x = -6; y = -1; title = "Land Grant / Foreven"; break;

                    case "imperium": x = -4; y = -1; w = 7; h = 5; title = "Third Imperium"; break;

                    case "solomani": x = -1.5; y = 2.75; w = 4; h = 2.25; title = "Solomani Confederacy"; break;

                    case "zhodani": x = -8; y = -3; w = 5; h = 3; title = "Zhodani Consulate"; break;

                    case "hive":
                    case "hiver": x = 2; y = 1; w = 6; h = 4; title = "Hive Federation"; break;

                    case "aslan": x = -8; y = 1; w = 7; h = 4; title = "Aslan Hierate"; break;

                    case "vargr": x = -4; y = -4; w = 8; h = 3; title = "Vargr Extents"; break;

                    case "kkree": x = 4; y = -2; w = 4; h = 4; title = "Two Thousand Worlds"; break;

                    case "jp": x = 0; y = -3; w = 4; h = 3; title = "Julian Protectorate"; break;
                    // TODO: Zhodani provinces

                    case "chartedspace": x = -8; y = -3; w = 16; h = 8; title = "Charted Space"; break;

                    case "jg": x = 160; y = 0; w = 2; h = 2; title = "Judges Guild"; break;

                    default:
                        throw new HttpError(404, "Not Found", $"Unknown domain: {domain}");
                    }

                    int x1 = (int)Math.Round(x * Astrometrics.SectorWidth - Astrometrics.ReferenceHex.X + 1);
                    int y1 = (int)Math.Round(y * Astrometrics.SectorHeight - Astrometrics.ReferenceHex.Y + 1);
                    int x2 = (int)Math.Round(x1 + w * Astrometrics.SectorWidth - 1);
                    int y2 = (int)Math.Round(y1 + h * Astrometrics.SectorHeight - 1);

                    tileRect = new RectangleF()
                    {
                        X = Math.Min(x1, x2),
                        Y = Math.Min(y1, y2)
                    };
                    tileRect.Width  = Math.Max(x1, x2) - tileRect.X;
                    tileRect.Height = Math.Max(y1, y2) - tileRect.Y;

                    // NOTE: This (re)initializes a static data structure used for
                    // resolving names into sector locations, so needs to be run
                    // before any other objects (e.g. Worlds) are loaded.
                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                    selector = new RectSelector(map, resourceManager, tileRect, slop: false);

                    // Include selected hexes
                    tileRect.Offset(-1, -1);
                    tileRect.Width  += 1;
                    tileRect.Height += 1;

                    // Account for jagged hexes
                    tileRect.Height += 0.5f;
                    tileRect.Inflate(0.25f, 0.10f);
                    if (style == Style.Candy)
                    {
                        tileRect.Width += 0.75f;
                    }

                    clipOutsectorBorders = true;
                }
                else
                {
                    // Sector - either POSTed or specified by name
                    Sector?sector = null;
                    options &= ~MapOptions.SectorGrid;

                    if (Context.Request.HttpMethod == "POST")
                    {
                        bool lint = GetBoolOption("lint", defaultValue: false);
                        Func <ErrorLogger.Record, bool>?filter = null;
                        if (lint)
                        {
                            bool hide_uwp = GetBoolOption("hide-uwp", defaultValue: false);
                            bool hide_tl  = GetBoolOption("hide-tl", defaultValue: false);
                            filter = (ErrorLogger.Record record) =>
                            {
                                if (hide_uwp && record.message.StartsWith("UWP"))
                                {
                                    return(false);
                                }
                                if (hide_tl && record.message.StartsWith("UWP: TL"))
                                {
                                    return(false);
                                }
                                return(true);
                            };
                        }
                        ErrorLogger errors = new ErrorLogger(filter);

                        sector = GetPostedSector(Context.Request, errors) ??
                                 throw new HttpError(400, "Bad Request", "Either file or data must be supplied in the POST data.");
                        if (lint && !errors.Empty)
                        {
                            throw new HttpError(400, "Bad Request", errors.ToString());
                        }


                        title = sector.Names.Count > 0 ? sector.Names[0].Text : "User Data";

                        // TODO: Suppress all OTU rendering.
                        options &= ~(MapOptions.WorldsHomeworlds | MapOptions.WorldsCapitals);
                    }
                    else
                    {
                        string sectorName = GetStringOption("sector") ??
                                            throw new HttpError(400, "Bad Request", "No sector specified.");

                        SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                        sector = map.FromName(sectorName) ??
                                 throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");

                        title = sector.Names[0].Text;
                    }

                    if (sector != null && HasOption("subsector") && GetStringOption("subsector") !.Length > 0)
                    {
                        string subsector = GetStringOption("subsector") !;
                        int    index     = sector.SubsectorIndexFor(subsector);
                        if (index == -1)
                        {
                            throw new HttpError(404, "Not Found", $"The specified subsector '{subsector}' was not found.");
                        }

                        selector = new SubsectorSelector(resourceManager, sector, index);

                        tileRect = sector.SubsectorBounds(index);

                        options &= ~(MapOptions.SectorGrid | MapOptions.SubsectorGrid);

                        title = $"{title} - Subsector {'A' + index}";
                    }
Пример #11
0
            public override void Process()
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                ResourceManager resourceManager = new ResourceManager(Context.Server);

                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                Sector           sector;

                SectorSerializeOptions options = new Serialization.SectorSerializeOptions();

                options.sscoords        = GetBoolOption("sscoords", defaultValue: false);
                options.includeMetadata = GetBoolOption("metadata", defaultValue: true);
                options.includeHeader   = GetBoolOption("header", defaultValue: true);
                options.includeRoutes   = GetBoolOption("routes", defaultValue: false);

                if (Context.Request.HttpMethod == "POST")
                {
                    bool lint   = GetBoolOption("lint", defaultValue: false);
                    var  errors = lint ? new ErrorLogger() : null;
                    sector = new Sector(Context.Request.InputStream, new ContentType(Context.Request.ContentType).MediaType, errors);
                    if (lint && !errors.Empty)
                    {
                        throw new HttpError(400, "Bad Request", errors.ToString());
                    }
                    options.includeMetadata = false;
                }
                else if (HasOption("sx") && HasOption("sy"))
                {
                    int sx = GetIntOption("sx", 0);
                    int sy = GetIntOption("sy", 0);

                    sector = map.FromLocation(sx, sy);

                    if (sector == null)
                    {
                        throw new HttpError(404, "Not Found", $"The sector at {sx},{sy} was not found.");
                    }
                }
                else if (HasOption("sector"))
                {
                    string sectorName = GetStringOption("sector");
                    sector = map.FromName(sectorName);

                    if (sector == null)
                    {
                        throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");
                    }
                }
                else
                {
                    throw new HttpError(400, "Bad Request", "No sector specified.");
                }

                if (HasOption("subsector"))
                {
                    string subsector = GetStringOption("subsector");
                    int    index     = sector.SubsectorIndexFor(subsector);
                    if (index == -1)
                    {
                        throw new HttpError(404, "Not Found", $"The specified subsector '{subsector}' was not found.");
                    }
                    options.filter = (World world) => (world.Subsector == index);
                }
                else if (HasOption("quadrant"))
                {
                    string quadrant = GetStringOption("quadrant");
                    int    index    = Sector.QuadrantIndexFor(quadrant);
                    if (index == -1)
                    {
                        throw new HttpError(400, "Bad Request", $"The specified quadrant '{quadrant}' is invalid.");
                    }
                    options.filter = (World world) => (world.Quadrant == index);
                }

                string   mediaType = GetStringOption("type");
                Encoding encoding;

                switch (mediaType)
                {
                case "SecondSurvey":
                case "TabDelimited":
                    encoding = Util.UTF8_NO_BOM;
                    break;

                default:
                    encoding = Encoding.GetEncoding(1252);
                    break;
                }

                string data;

                using (var writer = new StringWriter())
                {
                    // Content
                    //
                    sector.Serialize(resourceManager, writer, mediaType, options);
                    data = writer.ToString();
                }
                SendResult(Context, data, encoding);
            }
Пример #12
0
            public override void Process(ResourceManager resourceManager)
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                Location         loc = Location.Empty;

                if (HasOption("sector"))
                {
                    string sectorName = GetStringOption("sector");
                    Sector sec        = map.FromName(sectorName) ??
                                        throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");

                    int hex = GetIntOption("hex", Astrometrics.SectorCentralHex);
                    loc = new Location(sec.Location, hex);
                }
                else if (HasLocation())
                {
                    loc = GetLocation();
                }

                if (loc.Hex.IsEmpty)
                {
                    loc.Hex = Astrometrics.SectorCenter;
                }

                Sector sector = map.FromLocation(loc.Sector.X, loc.Sector.Y);

                var data = new Results.CreditsResult();

                if (sector != null)
                {
                    data.SectorX = sector.X;
                    data.SectorY = sector.Y;

                    // TODO: Multiple names
                    foreach (var name in sector.Names.Take(1))
                    {
                        data.SectorName = name.Text;
                    }

                    // Raw HTML credits
                    data.Credits = sector.Credits?.Trim();

                    // Product info
                    if (sector.Products.Count > 0)
                    {
                        data.ProductPublisher = sector.Products[0].Publisher;
                        data.ProductTitle     = sector.Products[0].Title;
                        data.ProductAuthor    = sector.Products[0].Author;
                        data.ProductRef       = sector.Products[0].Ref;
                    }

                    // Tags
                    data.SectorTags = sector.TagString;

                    //
                    // Sector Credits
                    //
                    data.SectorAuthor    = sector.Author;
                    data.SectorSource    = sector.Source;
                    data.SectorPublisher = sector.Publisher;
                    data.SectorCopyright = sector.Copyright;
                    data.SectorRef       = sector.Ref;
                    data.SectorMilieu    = sector.CanonicalMilieu;

                    if (sector.DataFile != null)
                    {
                        data.SectorAuthor    = sector.DataFile.Author ?? data.SectorAuthor;
                        data.SectorSource    = sector.DataFile.Source ?? data.SectorSource;
                        data.SectorPublisher = sector.DataFile.Publisher ?? data.SectorPublisher;
                        data.SectorCopyright = sector.DataFile.Copyright ?? data.SectorCopyright;
                        data.SectorRef       = sector.DataFile.Ref ?? data.SectorRef;
                        data.SectorMilieu    = sector.CanonicalMilieu;
                    }

                    //
                    // Subsector Credits
                    //
                    int       ssx = (loc.Hex.X - 1) / Astrometrics.SubsectorWidth;
                    int       ssy = (loc.Hex.Y - 1) / Astrometrics.SubsectorHeight;
                    int       ssi = ssx + ssy * 4;
                    Subsector ss  = sector.Subsector(ssi);
                    if (ss != null)
                    {
                        data.SubsectorIndex = ss.Index;
                        data.SubsectorName  = ss.Name;
                    }

                    //
                    // Routes Credits
                    //


                    //
                    // World Data
                    //
                    WorldCollection worlds = sector.GetWorlds(resourceManager);
                    if (worlds != null)
                    {
                        World world = worlds[loc.Hex];
                        if (world != null)
                        {
                            data.WorldName       = world.Name;
                            data.WorldHex        = world.Hex;
                            data.WorldUwp        = world.UWP;
                            data.WorldRemarks    = world.Remarks;
                            data.WorldIx         = world.Importance;
                            data.WorldEx         = world.Economic;
                            data.WorldCx         = world.Cultural;
                            data.WorldPbg        = world.PBG;
                            data.WorldAllegiance = sector.GetAllegianceFromCode(world.Allegiance)?.T5Code ?? "";
                        }
                    }
                }

                SendResult(data);
            }
Пример #13
0
            public override void Process()
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                ResourceManager resourceManager = new ResourceManager(context.Server);

                Selector   selector;
                RectangleF tileRect = new RectangleF();
                MapOptions options  = MapOptions.SectorGrid | MapOptions.SubsectorGrid | MapOptions.BordersMajor | MapOptions.BordersMinor | MapOptions.NamesMajor | MapOptions.NamesMinor | MapOptions.WorldsCapitals | MapOptions.WorldsHomeworlds;

                Stylesheet.Style style = Stylesheet.Style.Poster;
                ParseOptions(ref options, ref style);
                string title;
                bool   clipOutsectorBorders;

                if (HasOption("x1") && HasOption("x2") &&
                    HasOption("y1") && HasOption("y2"))
                {
                    // Arbitrary rectangle

                    int x1 = GetIntOption("x1", 0);
                    int x2 = GetIntOption("x2", 0);
                    int y1 = GetIntOption("y1", 0);
                    int y2 = GetIntOption("y2", 0);

                    tileRect.X      = Math.Min(x1, x2);
                    tileRect.Y      = Math.Min(y1, y2);
                    tileRect.Width  = Math.Max(x1, x2) - tileRect.X;
                    tileRect.Height = Math.Max(y1, y2) - tileRect.Y;

                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                    selector = new RectSelector(map, resourceManager, tileRect, slop: false);

                    tileRect.Offset(-1, -1);
                    tileRect.Width  += 1;
                    tileRect.Height += 1;

                    title = string.Format("Poster ({0},{1}) - ({2},{3})", x1, y1, x2, y2);
                    clipOutsectorBorders = true;
                }
                else if (HasOption("domain"))
                {
                    string domain = GetStringOption("domain");
                    double x, y, w = 2, h = 2;
                    switch (domain.ToLowerInvariant())
                    {
                    case "deneb": x = -4; y = -1; title = "Domain of Deneb"; break;

                    case "vland": x = -2; y = -1; title = "Domain of Vland"; break;

                    case "ilelish": x = -2; y = 1; title = "Domain of Ilelish"; break;

                    case "antares": x = 0; y = -2; title = "Domain of Antares"; break;

                    case "sylea": x = 0; y = 0; title = "Domain of Sylea"; break;

                    case "sol": x = 0; y = 2; title = "Domain of Sol"; break;

                    case "gateway": x = 2; y = 0; title = "Domain of Gateway"; break;

                    // And these aren't domains, but...
                    case "foreven": x = -6; y = -1; title = "Land Grant / Foreven"; break;

                    case "imperium": x = -4; y = -1; w = 7; h = 5; title = "Third Imperium"; break;

                    case "solomani": x = -1.5; y = 2.75; w = 4; h = 2.25; title = "Solomani Confederacy"; break;

                    case "zhodani": x = -8; y = -3; w = 5; h = 3; title = "Zhodani Consulate"; break;

                    case "hive":
                    case "hiver": x = 2; y = 1; w = 6; h = 4; title = "Hiver Federation"; break;

                    case "aslan": x = -8; y = 1; w = 7; h = 4; title = "Aslan Hierate"; break;

                    case "vargr": x = -4; y = -4; w = 8; h = 3; title = "Vargr Extents"; break;

                    case "kkree": x = 4; y = -2; w = 4; h = 4; title = "Two Thousand Worlds"; break;

                    case "jp": x = 0; y = -3; w = 4; h = 3; title = "Julian Protectorate"; break;
                    // TODO: Zhodani provinces

                    case "chartedspace": x = -8; y = -3; w = 16; h = 8; title = "Charted Space"; break;

                    case "jg": x = 160; y = 0; w = 2; h = 2; title = "Judges Guild"; break;

                    default:
                        throw new HttpError(404, "Not Found", string.Format("Unknown domain: {0}", domain));
                    }

                    int x1 = (int)Math.Round(x * Astrometrics.SectorWidth - Astrometrics.ReferenceHex.X + 1);
                    int y1 = (int)Math.Round(y * Astrometrics.SectorHeight - Astrometrics.ReferenceHex.Y + 1);
                    int x2 = (int)Math.Round(x1 + w * Astrometrics.SectorWidth - 1);
                    int y2 = (int)Math.Round(y1 + h * Astrometrics.SectorHeight - 1);

                    tileRect.X      = Math.Min(x1, x2);
                    tileRect.Y      = Math.Min(y1, y2);
                    tileRect.Width  = Math.Max(x1, x2) - tileRect.X;
                    tileRect.Height = Math.Max(y1, y2) - tileRect.Y;

                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                    selector = new RectSelector(map, resourceManager, tileRect, slop: false);

                    tileRect.Offset(-1, -1);
                    tileRect.Width  += 1;
                    tileRect.Height += 1;

                    // Account for jagged hexes
                    tileRect.Height += 0.5f;
                    tileRect.Inflate(0.25f, 0.10f);
                    if (style == Stylesheet.Style.Candy)
                    {
                        tileRect.Width += 0.75f;
                    }

                    clipOutsectorBorders = true;
                }
                else
                {
                    // Sector - either POSTed or specified by name
                    Sector sector = null;
                    options = options & ~MapOptions.SectorGrid;

                    if (context.Request.HttpMethod == "POST")
                    {
                        bool        lint   = GetBoolOption("lint", defaultValue: false);
                        ErrorLogger errors = new ErrorLogger();
                        sector = GetPostedSector(context.Request, errors);
                        if (lint && !errors.Empty)
                        {
                            throw new HttpError(400, "Bad Request", errors.ToString());
                        }

                        if (sector == null)
                        {
                            throw new HttpError(400, "Bad Request", "Either file or data must be supplied in the POST data.");
                        }

                        title = "User Data";

                        // TODO: Suppress all OTU rendering.
                        options = options & ~MapOptions.WorldsHomeworlds & ~MapOptions.WorldsCapitals;
                    }
                    else
                    {
                        string sectorName = GetStringOption("sector");
                        if (sectorName == null)
                        {
                            throw new HttpError(400, "Bad Request", "No sector specified.");
                        }

                        SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                        sector = map.FromName(sectorName);
                        if (sector == null)
                        {
                            throw new HttpError(404, "Not Found", string.Format("The specified sector '{0}' was not found.", sectorName));
                        }

                        title = sector.Names[0].Text;
                    }

                    if (sector != null && HasOption("subsector") && GetStringOption("subsector").Length > 0)
                    {
                        options = options & ~MapOptions.SubsectorGrid;
                        string subsector = GetStringOption("subsector");
                        int    index     = sector.SubsectorIndexFor(subsector);
                        if (index == -1)
                        {
                            throw new HttpError(404, "Not Found", string.Format("The specified subsector '{0}' was not found.", subsector));
                        }

                        selector = new SubsectorSelector(resourceManager, sector, index);

                        tileRect = sector.SubsectorBounds(index);

                        options &= ~(MapOptions.SectorGrid | MapOptions.SubsectorGrid);

                        title = string.Format("{0} - Subsector {1}", title, 'A' + index);
                    }
                    else if (sector != null && HasOption("quadrant") && GetStringOption("quadrant").Length > 0)
                    {
                        string quadrant = GetStringOption("quadrant");
                        int    index;
                        switch (quadrant.ToLowerInvariant())
                        {
                        case "alpha": index = 0; quadrant = "Alpha"; break;

                        case "beta": index = 1; quadrant = "Beta"; break;

                        case "gamma": index = 2; quadrant = "Gamma"; break;

                        case "delta": index = 3; quadrant = "Delta"; break;

                        default:
                            throw new HttpError(400, "Bad Request", string.Format("The specified quadrant '{0}' is invalid.", quadrant));
                        }

                        selector = new QuadrantSelector(resourceManager, sector, index);
                        tileRect = sector.QuadrantBounds(index);

                        options &= ~(MapOptions.SectorGrid | MapOptions.SubsectorGrid | MapOptions.SectorsMask);

                        title = string.Format("{0} - {1} Quadrant", title, quadrant);
                    }
                    else
                    {
                        selector = new SectorSelector(resourceManager, sector);
                        tileRect = sector.Bounds;

                        options &= ~(MapOptions.SectorGrid);
                    }

                    // Account for jagged hexes
                    tileRect.Height += 0.5f;
                    tileRect.Inflate(0.25f, 0.10f);
                    if (style == Stylesheet.Style.Candy)
                    {
                        tileRect.Width += 0.75f;
                    }
                    clipOutsectorBorders = false;
                }

                const double NormalScale = 64; // pixels/parsec - standard subsector-rendering scale
                double       scale       = Util.Clamp(GetDoubleOption("scale", NormalScale), MinScale, MaxScale);

                int  rot   = GetIntOption("rotation", 0) % 4;
                bool thumb = GetBoolOption("thumb", false);

                Stylesheet stylesheet = new Stylesheet(scale, options, style);

                Size tileSize = new Size((int)Math.Floor(tileRect.Width * scale * Astrometrics.ParsecScaleX), (int)Math.Floor(tileRect.Height * scale * Astrometrics.ParsecScaleY));

                if (thumb)
                {
                    tileSize.Width  = (int)Math.Floor(16 * tileSize.Width / scale);
                    tileSize.Height = (int)Math.Floor(16 * tileSize.Height / scale);
                    scale           = 16;
                }

                int   bitmapWidth = tileSize.Width, bitmapHeight = tileSize.Height;
                float translateX = 0, translateY = 0;

                switch (rot)
                {
                case 1:     // 90 degrees clockwise
                    Util.Swap(ref bitmapWidth, ref bitmapHeight);
                    translateX = bitmapWidth;
                    break;

                case 2:     // 180 degrees
                    translateX = bitmapWidth; translateY = bitmapHeight;
                    break;

                case 3:     // 270 degrees clockwise
                    Util.Swap(ref bitmapWidth, ref bitmapHeight);
                    translateY = bitmapHeight;
                    break;
                }

                RenderContext ctx = new RenderContext(resourceManager, selector, tileRect, scale, options, stylesheet, tileSize);

                ctx.ClipOutsectorBorders = clipOutsectorBorders;
                ProduceResponse(context, title, ctx, new Size(bitmapWidth, bitmapHeight), rot, translateX, translateY);
            }
Пример #14
0
            public override void Process()
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                ResourceManager resourceManager = new ResourceManager(Context.Server);

                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                Location loc = new Location(map.FromName("Spinward Marches").Location, 1910);

                // Accept either sector [& hex] or sx,sy [& hx,hy] or x,y
                if (HasOption("sector"))
                {
                    string sectorName = GetStringOption("sector");
                    Sector sector     = map.FromName(sectorName);
                    if (sector == null)
                    {
                        throw new HttpError(404, "Not Found", string.Format("The specified sector '{0}' was not found.", sectorName));
                    }

                    if (HasOption("subsector"))
                    {
                        string subsector = GetStringOption("subsector");
                        int    index     = sector.SubsectorIndexFor(subsector);
                        if (index == -1)
                        {
                            throw new HttpError(404, "Not Found", string.Format("The specified subsector '{0}' was not found.", subsector));
                        }
                        int ssx = index % 4;
                        int ssy = index / 4;
                        Hex hex = new Hex(
                            (byte)(ssx * Astrometrics.SubsectorWidth + Astrometrics.SubsectorWidth / 2),
                            (byte)(ssy * Astrometrics.SubsectorHeight + Astrometrics.SubsectorHeight / 2));
                        loc = new Location(sector.Location, hex);
                    }
                    else
                    {
                        int hex = GetIntOption("hex", 0);
                        loc = new Location(sector.Location, hex);
                    }
                }
                else if (HasLocation())
                {
                    loc = GetLocation();
                }
                else
                {
                    throw new HttpError(400, "Bad Request", "Must specify either sector name (and optional hex) or sx, sy (and optional hx, hy), or x, y (world-space coordinates).");
                }

                Point coords = Astrometrics.LocationToCoordinates(loc);

                var result = new Results.CoordinatesResult();

                result.sx = loc.Sector.X;
                result.sy = loc.Sector.Y;
                result.hx = loc.Hex.X;
                result.hy = loc.Hex.Y;
                result.x  = coords.X;
                result.y  = coords.Y;
                SendResult(context, result);
            }
Пример #15
0
            public override void Process(ResourceManager resourceManager)
            {
                Selector   selector;
                RectangleF tileRect;
                MapOptions options = MapOptions.SectorGrid | MapOptions.SubsectorGrid | MapOptions.BordersMajor | MapOptions.BordersMinor | MapOptions.NamesMajor | MapOptions.NamesMinor | MapOptions.WorldsCapitals | MapOptions.WorldsHomeworlds;
                Style      style   = Style.Poster;

                ParseOptions(ref options, ref style);
                string title;
                bool   clipOutsectorBorders;

                if (HasOption("x1") && HasOption("x2") &&
                    HasOption("y1") && HasOption("y2"))
                {
                    // Arbitrary rectangle

                    int x1 = GetIntOption("x1", 0);
                    int x2 = GetIntOption("x2", 0);
                    int y1 = GetIntOption("y1", 0);
                    int y2 = GetIntOption("y2", 0);

                    tileRect = new RectangleF()
                    {
                        X = Math.Min(x1, x2),
                        Y = Math.Min(y1, y2)
                    };
                    tileRect.Width  = Math.Max(x1, x2) - tileRect.X;
                    tileRect.Height = Math.Max(y1, y2) - tileRect.Y;

                    // NOTE: This (re)initializes a static data structure used for
                    // resolving names into sector locations, so needs to be run
                    // before any other objects (e.g. Worlds) are loaded.
                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                    selector = new RectSelector(map, resourceManager, tileRect, slop: false);

                    // Include specified hexes
                    tileRect.Offset(-1, -1);
                    tileRect.Width  += 1;
                    tileRect.Height += 1;

                    title = $"Poster ({x1},{y1}) - ({x2},{y2})";
                    clipOutsectorBorders = true;
                }
                else if (HasOption("domain"))
                {
                    string domain = GetStringOption("domain");
                    double x, y, w = 2, h = 2;
                    switch (domain.ToLowerInvariant())
                    {
                    case "deneb": x = -4; y = -1; title = "Domain of Deneb"; break;

                    case "vland": x = -2; y = -1; title = "Domain of Vland"; break;

                    case "ilelish": x = -2; y = 1; title = "Domain of Ilelish"; break;

                    case "antares": x = 0; y = -2; title = "Domain of Antares"; break;

                    case "sylea": x = 0; y = 0; title = "Domain of Sylea"; break;

                    case "sol": x = 0; y = 2; title = "Domain of Sol"; break;

                    case "gateway": x = 2; y = 0; title = "Domain of Gateway"; break;

                    // And these aren't domains, but...
                    case "foreven": x = -6; y = -1; title = "Land Grant / Foreven"; break;

                    case "imperium": x = -4; y = -1; w = 7; h = 5; title = "Third Imperium"; break;

                    case "solomani": x = -1.5; y = 2.75; w = 4; h = 2.25; title = "Solomani Confederacy"; break;

                    case "zhodani": x = -8; y = -3; w = 5; h = 3; title = "Zhodani Consulate"; break;

                    case "hive":
                    case "hiver": x = 2; y = 1; w = 6; h = 4; title = "Hiver Federation"; break;

                    case "aslan": x = -8; y = 1; w = 7; h = 4; title = "Aslan Hierate"; break;

                    case "vargr": x = -4; y = -4; w = 8; h = 3; title = "Vargr Extents"; break;

                    case "kkree": x = 4; y = -2; w = 4; h = 4; title = "Two Thousand Worlds"; break;

                    case "jp": x = 0; y = -3; w = 4; h = 3; title = "Julian Protectorate"; break;
                    // TODO: Zhodani provinces

                    case "chartedspace": x = -8; y = -3; w = 16; h = 8; title = "Charted Space"; break;

                    case "jg": x = 160; y = 0; w = 2; h = 2; title = "Judges Guild"; break;

                    default:
                        throw new HttpError(404, "Not Found", $"Unknown domain: {domain}");
                    }

                    int x1 = (int)Math.Round(x * Astrometrics.SectorWidth - Astrometrics.ReferenceHex.X + 1);
                    int y1 = (int)Math.Round(y * Astrometrics.SectorHeight - Astrometrics.ReferenceHex.Y + 1);
                    int x2 = (int)Math.Round(x1 + w * Astrometrics.SectorWidth - 1);
                    int y2 = (int)Math.Round(y1 + h * Astrometrics.SectorHeight - 1);

                    tileRect = new RectangleF()
                    {
                        X = Math.Min(x1, x2),
                        Y = Math.Min(y1, y2)
                    };
                    tileRect.Width  = Math.Max(x1, x2) - tileRect.X;
                    tileRect.Height = Math.Max(y1, y2) - tileRect.Y;

                    // NOTE: This (re)initializes a static data structure used for
                    // resolving names into sector locations, so needs to be run
                    // before any other objects (e.g. Worlds) are loaded.
                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                    selector = new RectSelector(map, resourceManager, tileRect, slop: false);

                    // Include selected hexes
                    tileRect.Offset(-1, -1);
                    tileRect.Width  += 1;
                    tileRect.Height += 1;

                    // Account for jagged hexes
                    tileRect.Height += 0.5f;
                    tileRect.Inflate(0.25f, 0.10f);
                    if (style == Style.Candy)
                    {
                        tileRect.Width += 0.75f;
                    }

                    clipOutsectorBorders = true;
                }
                else
                {
                    // Sector - either POSTed or specified by name
                    Sector sector = null;
                    options &= ~MapOptions.SectorGrid;

                    if (Context.Request.HttpMethod == "POST")
                    {
                        bool lint = GetBoolOption("lint", defaultValue: false);
                        Func <ErrorLogger.Record, bool> filter = null;
                        if (lint)
                        {
                            bool hide_uwp = GetBoolOption("hide-uwp", defaultValue: false);
                            bool hide_tl  = GetBoolOption("hide-tl", defaultValue: false);
                            filter = (ErrorLogger.Record record) =>
                            {
                                if (hide_uwp && record.message.StartsWith("UWP"))
                                {
                                    return(false);
                                }
                                if (hide_tl && record.message.StartsWith("UWP: TL"))
                                {
                                    return(false);
                                }
                                return(true);
                            };
                        }
                        ErrorLogger errors = new ErrorLogger(filter);

                        sector = GetPostedSector(Context.Request, errors) ??
                                 throw new HttpError(400, "Bad Request", "Either file or data must be supplied in the POST data.");
                        if (lint && !errors.Empty)
                        {
                            throw new HttpError(400, "Bad Request", errors.ToString());
                        }


                        title = "User Data";

                        // TODO: Suppress all OTU rendering.
                        options &= ~(MapOptions.WorldsHomeworlds | MapOptions.WorldsCapitals);
                    }
                    else
                    {
                        string sectorName = GetStringOption("sector") ??
                                            throw new HttpError(400, "Bad Request", "No sector specified.");

                        SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                        sector = map.FromName(sectorName) ??
                                 throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");

                        title = sector.Names[0].Text;
                    }

                    if (sector != null && HasOption("subsector") && GetStringOption("subsector").Length > 0)
                    {
                        string subsector = GetStringOption("subsector");
                        int    index     = sector.SubsectorIndexFor(subsector);
                        if (index == -1)
                        {
                            throw new HttpError(404, "Not Found", $"The specified subsector '{subsector}' was not found.");
                        }

                        selector = new SubsectorSelector(resourceManager, sector, index);

                        tileRect = sector.SubsectorBounds(index);

                        options &= ~(MapOptions.SectorGrid | MapOptions.SubsectorGrid);

                        title = $"{title} - Subsector {'A' + index}";
                    }
                    else if (sector != null && HasOption("quadrant") && GetStringOption("quadrant").Length > 0)
                    {
                        string quadrant = GetStringOption("quadrant");
                        int    index;
                        switch (quadrant.ToLowerInvariant())
                        {
                        case "alpha": index = 0; quadrant = "Alpha"; break;

                        case "beta": index = 1; quadrant = "Beta"; break;

                        case "gamma": index = 2; quadrant = "Gamma"; break;

                        case "delta": index = 3; quadrant = "Delta"; break;

                        default:
                            throw new HttpError(400, "Bad Request", $"The specified quadrant '{quadrant}' is invalid.");
                        }

                        selector = new QuadrantSelector(resourceManager, sector, index);
                        tileRect = sector.QuadrantBounds(index);

                        options &= ~(MapOptions.SectorGrid | MapOptions.SubsectorGrid | MapOptions.SectorsMask);

                        title = $"{title} - {quadrant} Quadrant";
                    }
                    else
                    {
                        selector = new SectorSelector(resourceManager, sector);
                        tileRect = sector.Bounds;

                        options &= ~(MapOptions.SectorGrid);
                    }

                    // Account for jagged hexes
                    tileRect.Height += 0.5f;
                    tileRect.Inflate(0.25f, 0.10f);
                    if (style == Style.Candy)
                    {
                        tileRect.Width += 0.75f;
                    }
                    clipOutsectorBorders = false;
                }

                const double NormalScale = 64; // pixels/parsec - standard subsector-rendering scale
                double       scale       = GetDoubleOption("scale", NormalScale).Clamp(MinScale, MaxScale);

                int  rot   = GetIntOption("rotation", 0) % 4;
                int  hrot  = GetIntOption("hrotation", 0);
                bool thumb = GetBoolOption("thumb", false);

                Stylesheet stylesheet = new Stylesheet(scale, options, style);

                Size tileSize = new Size((int)Math.Floor(tileRect.Width * scale * Astrometrics.ParsecScaleX), (int)Math.Floor(tileRect.Height * scale * Astrometrics.ParsecScaleY));

                if (thumb)
                {
                    tileSize.Width  = (int)Math.Floor(16 * tileSize.Width / scale);
                    tileSize.Height = (int)Math.Floor(16 * tileSize.Height / scale);
                    scale           = 16;
                }

                int            bitmapWidth = tileSize.Width, bitmapHeight = tileSize.Height;
                AbstractMatrix transform = AbstractMatrix.Identity;

                switch (rot)
                {
                case 1:     // 90 degrees clockwise
                    transform.RotatePrepend(90);
                    transform.TranslatePrepend(0, -bitmapHeight);
                    Util.Swap(ref bitmapWidth, ref bitmapHeight);
                    break;

                case 2:     // 180 degrees
                    transform.RotatePrepend(180);
                    transform.TranslatePrepend(-bitmapWidth, -bitmapHeight);
                    break;

                case 3:     // 270 degrees clockwise
                    transform.RotatePrepend(270);
                    transform.TranslatePrepend(-bitmapWidth, 0);
                    Util.Swap(ref bitmapWidth, ref bitmapHeight);
                    break;
                }

                // TODO: Figure out how to compose rot and hrot properly.
                Size bitmapSize = new Size(bitmapWidth, bitmapHeight);

                if (hrot != 0)
                {
                    ApplyHexRotation(hrot, stylesheet, ref bitmapSize, ref transform);
                }

                if (GetBoolOption("clampar", defaultValue: false))
                {
                    // Landscape: 1.91:1 (1.91)
                    // Portrait: 4:5 (0.8)
                    const double MIN_ASPECT_RATIO = 0.8;
                    const double MAX_ASPECT_RATIO = 1.91;
                    double       aspectRatio      = (double)bitmapSize.Width / (double)bitmapSize.Height;
                    Size         newSize          = bitmapSize;
                    if (aspectRatio < MIN_ASPECT_RATIO)
                    {
                        newSize.Width = (int)Math.Floor(bitmapSize.Height * MIN_ASPECT_RATIO);
                    }
                    else if (aspectRatio > MAX_ASPECT_RATIO)
                    {
                        newSize.Height = (int)Math.Floor(bitmapSize.Width / MAX_ASPECT_RATIO);
                    }
                    if (newSize != bitmapSize)
                    {
                        transform.TranslatePrepend(
                            (newSize.Width - bitmapSize.Width) / 2f,
                            (newSize.Height - bitmapSize.Height) / 2f);
                        bitmapSize = newSize;
                    }
                }

                RenderContext ctx = new RenderContext(resourceManager, selector, tileRect, scale, options, stylesheet, tileSize)
                {
                    ClipOutsectorBorders = clipOutsectorBorders
                };

                ProduceResponse(Context, title, ctx, bitmapSize, transform);
            }
Пример #16
0
            public override void Process()
            {
                string query = context.Request.QueryString["q"];

                if (query == null)
                {
                    return;
                }

                // Look for special searches
                if (SpecialSearches.ContainsKey(query))
                {
                    string path = SpecialSearches[query];

                    if (context.Request.QueryString["jsonp"] != null)
                    {
                        // TODO: Does this include the JSONP headers?
                        SendFile(JsonConstants.MediaType, path);
                        return;
                    }

                    if (Accepts(context, JsonConstants.MediaType))
                    {
                        SendFile(JsonConstants.MediaType, path);
                        return;
                    }
                    return;
                }

                //
                // Do the search
                //
                ResourceManager resourceManager = new ResourceManager(context.Server);

                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                query = query.Replace('*', '%'); // Support * and % as wildcards
                query = query.Replace('?', '_'); // Support ? and _ as wildcards

                if (UWP_REGEXP.IsMatch(query))
                {
                    query = "uwp:" + query;
                }

                const int NUM_RESULTS = 160;

                var searchResults = SearchEngine.PerformSearch(query, SearchEngine.SearchResultsType.Default, NUM_RESULTS);

                SearchResults resultsList = new SearchResults();

                if (searchResults != null)
                {
                    resultsList.AddRange(searchResults
                                         .Select(loc => SearchResults.LocationToSearchResult(map, resourceManager, loc))
                                         .OfType <SearchResults.Item>()
                                         .OrderByDescending(item => item.Importance)
                                         .Take(NUM_RESULTS));
                }

                SendResult(context, resultsList);
            }
Пример #17
0
            public override void Process(ResourceManager resourceManager)
            {
                string query = Context.Request.QueryString["q"];

                if (query == null)
                {
                    return;
                }

                // Look for special searches
                if (SpecialSearches.ContainsKey(query))
                {
                    string path = SpecialSearches[query];

                    if (Context.Request.QueryString["jsonp"] != null)
                    {
                        // TODO: Does this include the JSONP headers?
                        SendFile(JsonConstants.MediaType, path);
                        return;
                    }

                    if (Accepts(Context, JsonConstants.MediaType))
                    {
                        SendFile(JsonConstants.MediaType, path);
                        return;
                    }
                    return;
                }

                //
                // Do the search
                //
                string milieu = GetStringOption("milieu", SectorMap.DEFAULT_MILIEU);

                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, milieu);

                int NUM_RESULTS;
                IEnumerable <SearchResult> searchResults;

                if (query == "(random world)")
                {
                    NUM_RESULTS   = 1;
                    searchResults = SearchEngine.PerformSearch(milieu, null, SearchEngine.SearchResultsType.Worlds, NUM_RESULTS, random: true);
                }
                else
                {
                    SearchEngine.SearchResultsType types = 0;
                    foreach (var type in GetStringsOption("types", new string[] { "default" }))
                    {
                        switch (type)
                        {
                        case "worlds": types |= SearchEngine.SearchResultsType.Worlds; break;

                        case "subsectors": types |= SearchEngine.SearchResultsType.Subsectors; break;

                        case "sectors": types |= SearchEngine.SearchResultsType.Sectors; break;

                        case "labels": types |= SearchEngine.SearchResultsType.Labels; break;

                        case "default": types |= SearchEngine.SearchResultsType.Default; break;
                        }
                    }

                    query = query.Replace('*', '%'); // Support * and % as wildcards
                    query = query.Replace('?', '_'); // Support ? and _ as wildcards

                    if (UWP_REGEXP.IsMatch(query))
                    {
                        query = "uwp:" + query;
                    }

                    NUM_RESULTS   = 160;
                    searchResults = SearchEngine.PerformSearch(milieu, query, types, NUM_RESULTS);
                }

                SearchResults resultsList = new SearchResults();

                if (searchResults != null)
                {
                    resultsList.AddRange(searchResults
                                         .Select(loc => SearchResults.SearchResultToItem(map, resourceManager, loc))
                                         .OfType <SearchResults.Item>()
                                         .OrderByDescending(item => item.Importance)
                                         .Take(NUM_RESULTS));
                }

                SendResult(resultsList);
            }
Пример #18
0
            public override void Process()
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                ResourceManager resourceManager = new ResourceManager(context.Server);

                //
                // Jump
                //
                int jump = Util.Clamp(GetIntOption("jump", 6), 0, 12);

                //
                // Content & Coordinates
                //
                Selector selector;
                Location loc;

                if (context.Request.HttpMethod == "POST")
                {
                    Sector      sector;
                    bool        lint   = GetBoolOption("lint", defaultValue: false);
                    ErrorLogger errors = new ErrorLogger();
                    sector = GetPostedSector(context.Request, errors);
                    if (lint && !errors.Empty)
                    {
                        throw new HttpError(400, "Bad Request", errors.ToString());
                    }

                    if (sector == null)
                    {
                        throw new HttpError(400, "Bad Request", "Either file or data must be supplied in the POST data.");
                    }

                    int hex = GetIntOption("hex", Astrometrics.SectorCentralHex);
                    loc      = new Location(new Point(0, 0), hex);
                    selector = new HexSectorSelector(resourceManager, sector, loc.Hex, jump);
                }
                else
                {
                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                    if (HasOption("sector") && HasOption("hex"))
                    {
                        string sectorName = GetStringOption("sector");
                        int    hex        = GetIntOption("hex", 0);
                        Sector sector     = map.FromName(sectorName);
                        if (sector == null)
                        {
                            throw new HttpError(404, "Not Found", string.Format("The specified sector '{0}' was not found.", sectorName));
                        }

                        loc = new Location(sector.Location, hex);
                    }
                    else if (HasLocation())
                    {
                        loc = GetLocation();
                    }
                    else
                    {
                        loc = new Location(map.FromName("Spinward Marches").Location, 1910);
                    }
                    selector = new HexSelector(map, resourceManager, loc, jump);
                }


                //
                // Scale
                //
                double scale = Util.Clamp(GetDoubleOption("scale", 64), MinScale, MaxScale);

                //
                // Options & Style
                //
                MapOptions options = MapOptions.BordersMajor | MapOptions.BordersMinor | MapOptions.ForceHexes;

                Stylesheet.Style style = Stylesheet.Style.Poster;
                ParseOptions(ref options, ref style);

                //
                // Border
                //
                bool border = GetBoolOption("border", defaultValue: true);

                //
                // Clip
                //
                bool clip = GetBoolOption("clip", defaultValue: true);

                //
                // What to render
                //

                RectangleF tileRect = new RectangleF();

                Point coords = Astrometrics.LocationToCoordinates(loc);

                tileRect.X      = coords.X - jump - 1;
                tileRect.Width  = jump + 1 + jump;
                tileRect.Y      = coords.Y - jump - 1;
                tileRect.Height = jump + 1 + jump;

                // Account for jagged hexes
                tileRect.Y += (coords.X % 2 == 0) ? 0 : 0.5f;
                tileRect.Inflate(0.35f, 0.15f);

                Size tileSize = new Size((int)Math.Floor(tileRect.Width * scale * Astrometrics.ParsecScaleX), (int)Math.Floor(tileRect.Height * scale * Astrometrics.ParsecScaleY));


                // Construct clipping path
                List <Point> clipPath = new List <Point>(jump * 6 + 1);
                Point        cur      = coords;

                for (int i = 0; i < jump; ++i)
                {
                    // Move J parsecs to the upper-left (start of border path logic)
                    cur = Astrometrics.HexNeighbor(cur, 1);
                }
                clipPath.Add(cur);
                for (int dir = 0; dir < 6; ++dir)
                {
                    for (int i = 0; i < jump; ++i)
                    {
                        cur = Astrometrics.HexNeighbor(cur, (dir + 3) % 6); // Clockwise from upper left
                        clipPath.Add(cur);
                    }
                }

                Stylesheet styles = new Stylesheet(scale, options, style);

                // If any names are showing, show them all
                if (styles.worldDetails.HasFlag(WorldDetails.KeyNames))
                {
                    styles.worldDetails |= WorldDetails.AllNames;
                }

                // Compute path
                float[] edgeX, edgeY;
                RenderUtil.HexEdges(styles.hexStyle == HexStyle.Square ? PathUtil.PathType.Square : PathUtil.PathType.Hex,
                                    out edgeX, out edgeY);
                PointF[] boundingPathCoords;
                byte[]   boundingPathTypes;
                PathUtil.ComputeBorderPath(clipPath, edgeX, edgeY, out boundingPathCoords, out boundingPathTypes);

                RenderContext ctx = new RenderContext(resourceManager, selector, tileRect, scale, options, styles, tileSize);

                ctx.DrawBorder           = border;
                ctx.ClipOutsectorBorders = true;

                // TODO: Widen path to allow for single-pixel border
                ctx.ClipPath = clip ? new AbstractPath(boundingPathCoords, boundingPathTypes) : null;
                ProduceResponse(context, "Jump Map", ctx, tileSize, transparent: clip);
            }
Пример #19
0
            public override void Process(ResourceManager resourceManager)
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                Sector           sector;

                SectorSerializeOptions options = new SectorSerializeOptions()
                {
                    sscoords        = GetBoolOption("sscoords", defaultValue: false),
                    includeMetadata = GetBoolOption("metadata", defaultValue: true),
                    includeHeader   = GetBoolOption("header", defaultValue: true),
                    includeRoutes   = GetBoolOption("routes", defaultValue: false)
                };

                if (Context.Request.HttpMethod == "POST")
                {
                    bool        lint   = GetBoolOption("lint", defaultValue: false);
                    ErrorLogger?errors = null;
                    if (lint)
                    {
                        bool hide_uwp = GetBoolOption("hide-uwp", defaultValue: false);
                        bool hide_tl  = GetBoolOption("hide-tl", defaultValue: false);
                        bool filter(ErrorLogger.Record record)
                        {
                            if (hide_uwp && record.message.StartsWith("UWP"))
                            {
                                return(false);
                            }
                            if (hide_tl && record.message.StartsWith("UWP: TL"))
                            {
                                return(false);
                            }
                            return(true);
                        }

                        errors = new ErrorLogger(filter);
                    }

                    try
                    {
                        sector = new Sector(Context.Request.InputStream, new ContentType(Context.Request.ContentType).MediaType, errors);
                    }
                    catch (ParseException ex)
                    {
                        if (!lint)
                        {
                            throw;
                        }
                        throw new HttpError(400, "Bad Request", $"Bad data file: {ex.Message}");
                    }
                    if (lint && errors != null && !errors.Empty)
                    {
                        throw new HttpError(400, "Bad Request", errors.ToString());
                    }
                    options.includeMetadata = false;
                }
                else if (HasOption("sx") && HasOption("sy"))
                {
                    int sx = GetIntOption("sx", 0);
                    int sy = GetIntOption("sy", 0);

                    sector = map.FromLocation(sx, sy) ??
                             throw new HttpError(404, "Not Found", $"The sector at {sx},{sy} was not found.");
                }
                else if (HasOption("sector"))
                {
                    string sectorName = GetStringOption("sector") !;
                    sector = map.FromName(sectorName) ??
                             throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");
                }
                else
                {
                    throw new HttpError(400, "Bad Request", "No sector specified.");
                }

                if (HasOption("subsector"))
                {
                    string subsector = GetStringOption("subsector") !;
                    int    index     = sector.SubsectorIndexFor(subsector);
                    if (index == -1)
                    {
                        throw new HttpError(404, "Not Found", $"The specified subsector '{subsector}' was not found.");
                    }
                    options.filter = (World world) => (world.Subsector == index);
                }
                else if (HasOption("quadrant"))
                {
                    string quadrant = GetStringOption("quadrant") !;
                    int    index    = Sector.QuadrantIndexFor(quadrant);
                    if (index == -1)
                    {
                        throw new HttpError(400, "Bad Request", $"The specified quadrant '{quadrant}' is invalid.");
                    }
                    options.filter = (World world) => (world.Quadrant == index);
                }

                string?  mediaType = GetStringOption("type");
                Encoding encoding  = mediaType switch
                {
                    "SecondSurvey" => Util.UTF8_NO_BOM,
                    "TabDelimited" => Util.UTF8_NO_BOM,
                    _ => Encoding.GetEncoding(1252),
                };

                string data;

                using (var writer = new StringWriter())
                {
                    // Content
                    //
                    sector.Serialize(resourceManager, writer, mediaType, options);
                    data = writer.ToString();
                }
                SendResult(data, encoding);
            }